Virgin import of ISC-DHCP v2.0b1pl6

This commit is contained in:
David E. O'Brien 1999-02-10 09:10:13 +00:00
commit cd2d014aab
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/isc-dhcp/dist/; revision=43829
svn path=/vendor/isc-dhcp/2.0b1-pl.6/; revision=43831; tag=vendor/isc-dhcp/2.0b1-pl.6
49 changed files with 15966 additions and 0 deletions

104
contrib/isc-dhcp/CHANGES Normal file
View File

@ -0,0 +1,104 @@
970609
- Don't trust hostnames provided by client - Win95 allows *spaces* in
client-supplied hostnames!
- Be lenient in parsing client-hostname statement in case a bad hostname
got recorded.
970607
- Change size_t to ssize_t in return values where a negative number
is used to indicate an error.
- Always write out two digits for single-byte quantities in arrays.
- When parsing a lease database, correctly transfer the client
hostname and hostname to the memory-resident lease structure.
- If the lease we want to give the client is different than the
one it's asking for, and we recognize the one it's asking for as
ours, NAK it.
- Only accept a DHCPRELEASE or DHCPNAK if the client supplies an IP
address and the lease corresponding to that address is available to
that client.
- Make it a warning rather than an error if resolv.conf is missing.
970605
- Add client-hostname token to lexer so that the parser can use it.
Fixes a serious lease database bug.
- Disable log message on receipt of short ICMP Echo replies.
970602
- Added DHCP Client scripts for FreeBSD, Solaris, and Linux, but
they're not guaranteed to work.
- Added some Cygwin32 (Windows NT/Windows 95) support, but this is not
sufficiently complete to be useful yet.
- Updated README
- Put something useful in TODO - formerly it mostly listed projects
that were way out on the back burner.
In DHCP Client:
- Add default, supersede, prepend and append option support, so that a
client can override or modify server-supplied options, and provide
default values if the server provides no values.
- Add reject keyword, so that packets from rogue DHCP or BOOTP servers
can be rejected out of hand.
- Added support for booting from BOOTP servers.
- Added BOOTP flag to client lease declaration, to indicated that a
particular lease was acquired through a BOOTP server.
- Don't try to do INIT-REBOOT on leases acquired from BOOTP servers.
- Print server's IP address instead of its IP address when logging
DHCP/BOOTP messages received by client.
- Fix some bugs in saved lease activation.
- Fix some scripting bugs.
- New sample dhclient.conf script demonstrates new features.
In common code:
- Partially implemented asynchronous DNS lookups.
- Fixed some bugs in dispatch routine.
- Fix date parsing bug that was setting dates forward one day every
time dhcpd was restarted (this has been fixed for a while in the 1.0
branch).
- Change name-server option name to ien116-name-server so as to reduce
the potential for confusion.
DHCP Relay daemon:
- Fixed an operator precedence bug having to do with the broadcast
flag.
DHCP Server:
- Add support to record the client-supplied hostname in the lease file,
for better readability.
- Fixed a bug in the renewal code that resulted in the server ignoring
unicast renewals from non-local subnets. This bug caused some
heartburn for Win95 machines.
- Copy ciaddr from saved ciaddr, not from giaddr.
- New -t flag tests /etc/dhcpd.conf for syntax errors.

236
contrib/isc-dhcp/README Normal file
View File

@ -0,0 +1,236 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 2, Beta 1, Patchlevel 0
December 6, 1997
This is the first Beta release of Version 2 of the Internet Software
Consortium DHCP Distribution. In version 2.0, this distribution
includes a DHCP server, a DHCP client, and a BOOTP/DHCP relay agent.
This beta is believed to be fairly stable. However, DHCP server users
running a production environment should probably still use version
1.0, which is more stable, having been in a feature freeze since
November of 1996.
In this release, the server and relay agent currently work well on
Digital Alpha OSF/1, SunOS 4.1.4, NetBSD, FreeBSD, BSD/OS and Ultrix.
They can also be run usefully on Solaris as long as only one broadcast
network interface is configured. They also runs on QNX and Linux as
long as only one broadcast network interface is configured and a host
route is added from that interface to the 255.255.255.255 broadcast
address. If you are running a Linux 2.0.31 kernel, the DHCP daemons
may be able to operate on more than one interface.
The DHCP client currently only knows how to configure the network on
NetBSD, FreeBSD, BSD/os, Linux, Solaris and NextStep. The client
depends on a system-dependent shell script to do network
configuration - support for other operating systems is simply a matter
of porting this shell script to the new platform.
If you wish to run the DHCP Distribution on Linux, please see the
Linux-specific notes later in this document. If you wish to run on a
SCO release, please see the SCO-specific notes later in this document.
You particularly need to read these notes if you intend to support
Windows 95 clients. If you are running a version of FreeBSD prior to
2.2, please read the note on FreeBSD. If you are running HP-UX or
Ultrix, please read the notes for those operating systems below.
If you are running NeXTSTEP, please see the notes on NeXTSTEP below.
If you start dhcpd and get a message, "no free bpf", that means you
need to configure the Berkeley Packet Filter into your operating
system kernel. On NetBSD, FreeBSD and BSD/os, type ``man bpf'' for
information. On Digital Unix, type ``man pfilt''.
BUILDING THE DHCP DISTRIBUTION
To build the DHCP Distribution, type ``configure''. If configure can
figure out what sort of system you're running on, it will create a
custom Makefile for you for that system; otherwise, it will complain.
If it can't figure out what system you are using, that system is not
supported - you are on your own.
Once you've run configure, just type ``make'', and after a while you
should have a dhcp server. If you get compile errors on one of the
supported systems mentioned earlier, please let us know. If you get
errors on a system not mentioned above, you will need to do some
programming or debugging on your own to get the DHCP Distribution working.
LINUX
There are three big LINUX issues: the all-ones broadcast address,
Linux 2.1 ip_bootp_agent enabling, and operations with more than one
network interface.
BROADCAST
In order for dhcpd to work correctly with picky DHCP clients (e.g.,
Windows 95), it must be able to send packets with an IP destination
address of 255.255.255.255. Unfortunately, Linux insists on changing
255.255.255.255 into the local subnet broadcast address (here, that's
192.5.5.223). This results in a DHCP protocol violation, and while
many DHCP clients don't notice the problem, some (e.g., all Microsoft
DHCP clients) do. Clients that have this problem will appear not to
see DHCPOFFER messages from the server.
It is possible to work around this problem on some versions of Linux
by creating a host route from your network interface address to
255.255.255.255. The command you need to use to do this on Linux
varies from version to version. The easiest version is:
route add -host 255.255.255.255 dev eth0
On some older Linux systems, you will get an error if you try to do
this. On those systems, try adding the following entry to your
/etc/hosts file:
255.255.255.255 all-ones
Then, try:
route add -host all-ones dev eth0
Another route that has worked for some users is:
route add -net 255.255.255.0 dev eth0
If you are not using eth0 as your network interface, you should
specify the network interface you *are* using in your route command.
IP BOOTP AGENT
Some versions of the Linux 2.1 kernel apparently prevent dhcpd from
working unless you enable it by doing the following:
echo 1 >/proc/sys/net/ipv4/ip_bootp_agent
MULTIPLE INTERFACES
Most older versions of the Linux kernel do not provide a networking
API that allows dhcpd to operate correctly if the system has more than
one broadcast network interface. However, Linux 2.0 kernels with
version numbers greater than or equal to 2.0.31 add an API feature:
the SO_BINDTODEVICE socket option. If SO_BINDTODEVICE is present, it
is possible for dhcpd to operate on Linux with more than one network
interface. In order to take advantage of this, you must be running a
2.0.31 or greater kernel, and you must have 2.0.31 system headers
installed *before* you build dhcpd.
NOTE: People have been having problems finding the 2.0.31 kernel
because it was only available as a prerelease patch. As of October
17, Linux 2.0.31 is the stable Linux kernel, and is available as a
kernel distribution rather than as a test patch. With any luck, it
will be in the latest version of your favourite Linux distribution
soon.
If you are running a Linux 2.1 kernel, this does not guarantee that you
have SO_BINDTODEVICE. Linux 2.0.31 was released quite a while after 2.1
kernel development began. The earliest Linux kernel in the 2.1
development stream with SO_BINDTODEVICE is version 2.1.68.
We have heard reports that you must still add routes to 255.255.255.255
in order for the all-ones broadcast to work, even on 2.0.31 kernels.
In fact, you now need to add a route for each interface. Hopefully
the Linux kernel gurus will get this straight eventually.
SCO
SCO has the same problem as Linux (described earlier). The thing is,
SCO *really* doesn't want to let you add a host route to the all-ones
broadcast address. One technique that has been successful on some
versions of SCO is the very bizarre command:
ifconfig net0 alias 10.1.1.1 netmask 8.0.0.0
Apparently this works because of an interaction between SCO's support
for network classes and the weird netmask. The 10.* network is just a
dummy that can generally be assumed to be safe. Don't ask why this
works. Just try it. If it works for you, great. If not, SCO is
supposedly adding hooks to support real DHCP service in a future
release - I have this on good authority from the people at SCO who do
*their* DHCP server and client.
HP-UX
HP-UX has the same problem with the all-ones broadcast address that
SCO and Linux have. One user reported that adding the following to
/etc/rc.config.d/netconf helped (you may have to modify this to suit
your local configuration):
INTERFACE_NAME[0]=lan0
IP_ADDRESS[0]=1.1.1.1
SUBNET_MASK[0]=255.255.255.0
BROADCAST_ADDRESS[0]="255.255.255.255"
LANCONFIG_ARGS[0]="ether"
DHCP_ENABLE[0]=0
ULTRIX
Now that we have Ultrix packet filter support, the DHCP Distribution
on Ultrix should be pretty trouble-free. However, one thing you do
need to be aware of is that it now requires that the pfilt device be
configured into your kernel and present in /dev. If you type ``man
packetfilter'', you will get some information on how to configure your
kernel for the packet filter (if it isn't already) and how to make an
entry for it in /dev.
FreeBSD
Versions of FreeBSD prior to 2.2 have a bug in BPF support in that the
ethernet driver swaps the ethertype field in the ethernet header
downstream from BPF, which corrupts the output packet. If you are
running a version of FreeBSD prior to 2.2, and you find that dhcpd
can't communicate with its clients, you should #define BROKEN_FREEBSD_BPF
in site.h and recompile.
NeXTSTEP
The NeXTSTEP support uses the NeXTSTEP Berkeley Packet Filter
extension, which is not included in the base NextStep system. You
must install this extension in order to get dhcpd or dhclient to work.
SUPPORT
The Internet Software Consortium DHCP server is not a commercial
product, and is not supported in that sense. However, it has
attracted a fairly sizable following on the Internet, which means that
there are a lot of knowledgable users who may be able to help you if
you get stuck. These people generally read the dhcp-server@fugue.com
mailing list.
If you are going to use dhcpd, you should probably subscribe to the
dhcp-server and dhcp-announce mailing lists. If you will be using
dhclient, you should subscribe to the dhcp-client mailing list.
PLEASE DO NOT send queries about non-isc clients to the dhcp-client
mailing list. If you're asking about them on an ISC mailing list,
it's probably because you're using the ISC DHCP server, so ask there.
Please see http://www.fugue.com/dhcp/lists for details on how to
subscribe. If you don't have WorldWide Web access, you can send mail
to dhcp-request@fugue.com and tell me which lists you want to
subscribe to, but please use the web interface if you can, since I
have to handle the -request mailing list manually, and I will give you
the third degree if you make me do your subscription manually.
PLEASE DO NOT SEND REQUESTS FOR SUPPORT DIRECTLY TO ME! The number of
people using the DHCP Distribution is sufficiently large that if I
take an interrupt every time any one of those people runs into
trouble, I will never get any more coding done.
PLEASE DO NOT CALL ME ON THE PHONE FOR SUPPORT! Answering the phone
takes a lot more of my time and attention than answering email. If you
do call me on the phone, I will tell you to send email to the mailing
list, and I won't answer your question, so there's no point in doing
it.
BUGS
This release of the DHCP Distribution does not yet contain support for
DHCPINFORM. Support for DHCPINFORM will be present in the release at
a later time. DHCPINFORM is somewhat tangential to the main purpose
of the DHCP protocol, so this probably won't be a major problem for
most users.
Vendor tags and User tags are not currently supported.

242
contrib/isc-dhcp/RELNOTES Normal file
View File

@ -0,0 +1,242 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 2, Beta 1, Patchlevel 6
June 26, 1998
Release Notes
This is the first Beta release of Version 2 of the Internet Software
Consortium DHCP Distribution. This beta is believed to be fairly
stable.
PLANS
Version 1 of the ISC DHCP Distribution includes just a DHCP Server.
Version 1 has been in feature freeze since late 1996, and is quite
stable. This is the release that we would expect most sites to run in
production.
Version 2 of the ISC DHCP Distribution adds a DHCP Client and a
DHCP/BOOTP Relay Agent to the DHCP Server that was offered in version
1.0. In addition, some new capabilities have been added to the
server:
- IP addresses are now tested before they are assigned to
clients. This allows the DHCP server to detect rogue
machines that may have hijacked IP addresses before an IP
address conflict can occur.
- The server may be configured so that some DHCP clients can
be excluded from booting.
- Improved NAKing behaviour, so that clients that are using
addresses other than the one the server knows they should be
using are disciplined quickly.
This version is now in Beta testing, and is planned for release in
mid-1998. It has a number of new features, and is the release that we
would expect sites that want some stability but need the new lease
testing feature, or need a client or relay agent. Note that it is
possible to run the Version 1 server with the Version 2 client.
Version 3 of the ISC DHCP Distribution will add Dynamic DNS Support,
asynchronous DNS query resolution, DHCP Authentication, and possibly
support for a DHCP Interserver Protocol and live querying of the DHCP
database. This release is not expected to be stable in the near
future, and is intended for sites that are in a position to
experiment, or for sites that desperately need the new features.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 5
- Define some extra DLPI support flags that make DLPI work much better
on Solaris.
- Fix inet_aton prototype/declaration to match Internet Software
Consortium BIND distribution.
- Document new server-identifier functionality.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 4
- Do not use -Wstrict-prototypes on Solaris with gcc - if the Internet
Software Consortium BIND distribution is not installed, this produces
errors.
- Actually use the new DLPI support on Solaris - although the code was
added in Patchlevel 2, it wasn't enabled (blush).
- Fix a prototype bug that's exposed when DLPI support is enabled on
Solaris.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 3
- Fix a makefile botch that prevents the DHCP Distribution from
from compiling on Solaris with gcc. Sigh.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 2
- Allow server-identifier in any scope. Use in-scope server
identifier option rather than the default, if one exists.
- Delete newlines from abandoned lease reclaimation warning.
- Only release other applicable leases held by a client when the
client sends a DHCPREQUEST.
- Fix core dump when find_lease didn't find a lease.
- Update dhcpd.leases man page.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 1
- Use -Wno-char-subscript on Solaris to prevent bogus warnings from
gcc on Solaris 2.6.
- Add support for Apple's new Rhapsody operating system.
- Use DLPI on Solaris instead of using the BSD Sockets API.
- Fix two network input buffer overflow problems which could allow an
attacker to pervert the stack.
- Fix an ancient typo that could theoretically cause memory
corruption.
- Sort abandoned leases in at current time rather than end of time.
This allows abandoned leases to be reclaimed if there are no
available free leases.
- If a client explicitly requests a lease that's been abandoned, it's
probably the system that was answering pings on that address, so let it
have the lease.
- Fix a bunch of type conversion errors that are flagged by the Solaris
C compiler.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 0
- Fix two potential buffer overflow problems.
- Differentiate between versions of Linux for better success in
compiling.
- Fix bug in linux client script regarding routing setup.
- Clarify socket API error message on multiple interfaces.
- Fix broken comparison that was setting IP source address to zero.
- Reclaim abandoned leases if we run out of free leases.
CHANGES FROM THE DECEMBER 2, 1997 SNAPSHOT
- Use %ld to print pid_t and cast pid_t values to long to avoid
inconsistent declarations between different POSIX flavours.
- Add support for ARPHRD_IEEE802 (token ring) hardware type.
- If we own an address and a client requests it, but we can't assign
it to that client, we now NAK it so that the client doesn't try to
reuse it.
CHANGES FROM THE JUNE SNAPSHOT
- Support for NeXTstep 3.x and 4.x
- Added man pages for dhcpd.leases, dhclient-script, dhclient.leases
and dhclient.conf. Move general documentation of DHCP options into
a seperate man page which is referred to by the dhclient.conf and
dhcpd.conf man pages.
- Updated README to answer some frequently asked questions.
- Fixed a bug in command-line interface specification in dhclient - it
was formerly not possible to specify that only certain interfaces be
configured.
- Do not leave client scripts lying around in /tmp after they've been
used unless the -D flag is specified.
- Add a new, non-standard, not-guaranteed-to-stay-the-same system
configuration status message server which can be used to trigger the
client to recheck its address, e.g., after a laptop has been put to
sleep and then awakened (this has yet to be documented).
- Fix handling of media selection in the REBOOT phase - previously the
media type would not be remembered, which could cause severe delays
in reacquiring an address if the default media type was wrong.
- Allocate space for a NUL terminator on the end of client options -
this was previously overlooked, and could cause garbage characters
to be written to the temporary client script files.
- Use mkstemp if it's available.
- Supply network number and broadcast address to the client script so
that on systems that need these values, they don't need to be
computed with an awk script.
- Keep a PID file for the client and the relay agent, and have the
relay agent background itself by default.
- Add client script for bsd/os, fix many niggling bugs in existing
client scripts and add support for static routing tables to all bsd
scripts.
- Add a -q option to the client, server and relay agent so that they
can be started from /etc/rc scripts without spewing a bunch of
garbage on the console. By default, all three daemons still print
startup messages, since these are helpful in bug reporting.
- Don't print anything to stderr or stdout after going into
background.
- Fix bug where hostname keyword was not being recognized in
dhcpd.leases file, resulting in the loss of lease database entries.
- Fix problem on some operating systems where zero-length ifreq
structures were being offset incorrectly when scanning the interface
list on startup.
- Unless a BOOTP client requests it, never send more than 64 bytes of
options.
- Don't ping static leases, since we don't have a lease structure on
the heap to work with later.
- Fixed a compile problem on Solaris 2.6.
- Support interface aliases on Solaris.
- Print day and month with leading zero in lease files if less than
ten, for easier parsing by perl/sed/awk scripts.
- Never make the lease database world writable, even if dhcpd is
invoked with a bogus umask.
- Fix DHCPRELEASE handling (before, addressed would never be
released.)
- If there is more than one lease for a particular client on a
particular network, find the lease the client is asking for so as to
avoid a cycle of NAKs.
- If a BOOTP request is received from a particular client and that
client has previously received a DHCP address, make sure that we
still find a valid BOOTP lease so that we don't cycle through
addresses.
- Remove server-identifier option from documentation, other than to
document that it has been deprecated.
- Don't give up if we get an EINTR or EAGAIN while polling or
selecting - these return statuses can occur spuriously without
indicating a fatal problem.
- Do not select for exceptions, since we don't handle them. This was
causing massive CPU consumption on some systems.
- When a DHCP client has been assigned a fixed address but had
previously had a lease, it will request the old leased address. In
such an event, send a DHCPNAK so that it will discover its new
static binding.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,191 @@
.\" dhclient-script.8
.\"
.\" Copyright (c) 1997 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of The Internet Software Consortium nor the names
.\" of its contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" This software has been written for the Internet Software Consortium
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
.\" Enterprises. To learn more about the Internet Software Consortium,
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
.\" Enterprises, see ``http://www.vix.com''.
.TH dhclient 8
.SH NAME
dhclient-script - DHCP client network configuration script
.SH DESCRIPTION
The DHCP client network configuration script is invoked from time to
time by \fBdhclient(8)\fR. This script is used by the dhcp client to
set each interface's initial configuration prior to requesting an
address, to test the address once it has been offered, and to set the
interface's final configuration once a lease has been acquired. If no
lease is acquired, the script is used to test predefined leases, if
any, and also called once if no valid lease can be identified.
.PP
This script is not meant to be customized by the end user. However,
the script may not work on particular versions of particular operating
systems (indeed, no standard script exists for some operating
systems), so a pioneering user may well need to create a new script or
modify an existing one. In general, customizations specific to a
particular computer should be done in the
.B ETCDIR/dhclient.conf
script. If you find that you can't make such a customization without
customizing dhclient.conf, please submit a bug report.
.SH OPERATION
When dhclient needs to invoke the client configuration script, it
writes a shell script into /tmp which defines a variety of variables.
In all cases, $reason is set to the name of the reason why the script
has been invoked. The following reasons are currently defined:
MEDIUM, PREINIT, ARPCHECK, ARPSEND, BOUND, RENEW, REBIND, REBOOT,
EXPIRE, FAIL and TIMEOUT.
.PP
.SH MEDIUM
The DHCP client is requesting that an interface's media type
be set. The interface name is passed in $interface, and the media
type is passed in $medium.
.SH PREINIT
The DHCP client is requesting that an interface be configured as
required in order to send packets prior to receiving an actual
address. For clients which use the BSD socket library, this means
configuring the interface with an IP address of 0.0.0.0 and a
broadcast address of 255.255.255.255. For other clients, it may be
possible to simply configure the interface up without actually giving
it an IP address at all. The interface name is passed in $interface,
and the media type in $medium.
.PP
If an IP alias has been declared in dhclient.conf, its address will be
passed in $alias_ip_address, and that ip alias should be deleted from
the interface, along with any routes to it.
.SH ARPSEND
The DHCP client is requesting that an address that has been offered to
it be checked to see if somebody else is using it, by sending an ARP
request for that address. It's not clear how to implement this, so
no examples exist yet. The IP address to check is passed in
$new_ip_address, and the interface name is passed in $interface.
.SH ARPCHECK
The DHCP client wants to know if a response to the ARP request send
using ARPCHECK has been received. If one has, the script should exit
with a nonzero status, indicating that the offered address has already
been requested and should be declined. $new_ip_address and
$interface are set as with ARPSEND.
.SH BOUND
The DHCP client has done an initial binding to a new address. The
new ip address is passed in $new_ip_address, and the interface name is
passed in $interface. The media type is passed in $medium. Any
options acquired from the server are passed using the option name
described in \fBdhcp-options\fR, except that dashes ('-') are replaced
by underscores ('_') in order to make valid shell variables, and the
variable names start with new_. So for example, the new subnet mask
would be passed in $new_subnet_mask.
.PP
When a binding has been completed, a lot of network parameters are
likely to need to be set up. A new /etc/resolv.conf needs to be
created, using the values of $new_domain_name and
$new_domain_name_servers (which may list more than one server,
seperated by spaces). A default route should be set using
$new_routers, and static routes may need to be set up using
$new_static_routes.
.PP
If an IP alias has been declared, it must be set up here. The alias
IP address will be written as $alias_ip_address, and other DHCP
options that are set for the alias (e.g., subnet mask) will be passed
in variables named as described previously except starting with
$alias_ instead of $new_. Care should be taken that the alias IP
address not be used if it is identical to the bound IP address
($new_ip_address), since the other alias parameters may be incorrect
in this case.
.SH RENEW
When a binding has been renewed, the script is called as in BOUND,
except that in addition to all the variables starting with $new_,
there is another set of variables starting with $old_. Persistent
settings that may have changed need to be deleted - for example, if a
local route to the bound address is being configured, the old local
route should be deleted. If the default route has changed, the old default
route should be deleted. If the static routes have changed, the old
ones should be deleted. Otherwise, processing can be done as with
BOUND.
.SH REBIND
The DHCP client has rebound to a new DHCP server. This can be handled
as with RENEW, except that if the IP address has changed, the ARP
table should be cleared.
.SH REBOOT
The DHCP client has successfully reacquired its old address after a
reboot. This can be processed as with BOUND.
.SH EXPIRE
The DHCP client has failed to renew its lease or acquire a new one,
and the lease has expired. The IP address must be relinquished, and
all related parameters should be deleted, as in RENEW and REBIND.
.SH FAIL
The DHCP client has been unable to contact any DHCP servers, and any
leases that have been tested have not proved to be valid. The
parameters from the last lease tested should be deconfigured. This
can be handled in the same way as EXPIRE.
.SH TIMEOUT
The DHCP client has been unable to contact any DHCP servers.
However, an old lease has been identified, and its parameters have
been passed in as with BOUND. The client configuration script should
test these parameters and, if it has reason to believe they are valid,
should exit with a value of zero. If not, it should exit with a
nonzero value.
.PP
The usual way to test a lease is to set up the network as with REBIND
(since this may be called to test more than one lease) and then ping
the first router defined in $routers. If a response is received, the
lease must be valid for the network to which the interface is
currently connected. It would be more complete to try to ping all of
the routers listed in $new_routers, as well as those listed in
$new_static_routes, but current scripts do not do this.
.SH FILES
Each operating system should generally have its own script file,
although the script files for similar operating systems may be similar
or even identical. The script files included in the Internet
Software Consortium DHCP distribution appear in the distribution tree
under client/scripts, and bear the names of the operating systems on
which they are intended to work.
.SH BUGS
If more than one interface is being used, there's no obvious way to
avoid clashes between server-supplied configuration parameters - for
example, the stock dhclient-script rewrites /etc/resolv.conf. If
more than one interface is being configured, /etc/resolv.conf will be
repeatedly initialized to the values provided by one server, and then
the other. Assuming the information provided by both servers is
valid, this shouldn't cause any real problems, but it could be
confusing.
.SH SEE ALSO
dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
dhclient.leases(5).
.SH AUTHOR
.B dhclient-script(8)
has been written for the Internet Software Consortium
by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
Enterprises. To learn more about the Internet Software Consortium,
see
.B http://www.vix.com/isc.
To learn more about Vixie
Enterprises, see
.B http://www.vix.com.

View File

@ -0,0 +1,163 @@
.\" dhclient.8
.\"
.\" Copyright (c) 1997 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of The Internet Software Consortium nor the names
.\" of its contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" This software has been written for the Internet Software Consortium
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
.\" Enterprises. To learn more about the Internet Software Consortium,
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
.\" Enterprises, see ``http://www.vix.com''.
.TH dhclient 8
.SH NAME
dhclient - Dynamic Host Configuration Protocol Client
.SH SYNOPSIS
.B dhclient
[
.B -p
.I port
]
[
.B -d
]
[
.I if0
[
.I ...ifN
]
]
.SH DESCRIPTION
The Internet Software Consortium DHCP Client, dhclient, provides a
means for configuring one or more network interfaces using the Dynamic
Host Configuration Protocol, BOOTP protocol, or if these protocols
fail, by statically assigning an address.
.SH OPERATION
.PP
The DHCP protocol allows a host to contact a central server which
maintains a list of IP addresses which may be assigned on one or more
subnets. A DHCP client may request an address from this pool, and
then use it on a temporary basis for communication on network. The
DHCP protocol also provides a mechanism whereby a client can learn
important details about the network to which it is attached, such as
the location of a default router, the location of a name server, and
so on.
.PP
On startup, dhclient reads the
.IR dhclient.conf
for configuration instructions. It then gets a list of all the
network interfaces that are configured in the current system. For
each interface, it attempts to configure the interface using the DHCP
protocol.
.PP
In order to keep track of leases across system reboots and server
restarts, dhclient keeps a list of leases it has been assigned in the
dhclient.leases(5) file. On startup, after reading the dhclient.conf
file, dhclient reads the dhclient.leases file to refresh its memory
about what leases it has been assigned.
.PP
When a new lease is acquired, it is appended to the end of the
dhclient.leases file. In order to prevent the file from becoming
arbitrarily large, from time to time dhclient creates a new
dhclient.leases file from its in-core lease database. The old version
of the dhclient.leases file is retained under the name
.IR dhcpd.leases~
until the next time dhclient rewrites the database.
.PP
Old leases are kept around in case the DHCP server is unavailable when
dhclient is first invoked (generally during the initial system boot
process). In that event, old leases from the dhclient.leases file
which have not yet expired are tested, and if they are determined to
be valid, they are used until either they expire or the DHCP server
becomes available.
.PP
A mobile host which may sometimes need to access a network on which no
DHCP server exists may be preloaded with a lease for a fixed
address on that network. When all attempts to contact a DHCP server
have failed, dhclient will try to validate the static lease, and if it
succeeds, will use that lease until it is restarted.
.PP
A mobile host may also travel to some networks on which DHCP is not
available but BOOTP is. In that case, it may be advantageous to
arrange with the network administrator for an entry on the BOOTP
database, so that the host can boot quickly on that network rather
than cycling through the list of old leases.
.SH COMMAND LINE
.PP
The names of the network interfaces that dhclient should attempt to
configure may be specified on the command line. If no interface names
are specified on the command line dhclient will identify all network
interfaces, elimininating non-broadcast interfaces if possible, and
attempt to configure each interface.
.PP
If dhclient should listen and transmit on a port other than the
standard (port 68), the
.B -p
flag may used. It should be followed by the udp port number that
dhclient should use. This is mostly useful for debugging purposes.
.PP
Dhclient will normally run in the foreground until it has configured
an interface, and then will revert to running in the background.
To run force dhclient to always run as a foreground process, the
.B -d
flag should be specified. This is useful when running dhclient under
a debugger, or when running it out of inittab on System V systems.
.PP
.SH CONFIGURATION
The syntax of the dhclient.conf(8) file is discussed seperately.
.SH FILES
.B ETCDIR/dhclient.conf, DBDIR/dhclient.leases, RUNDIR/dhclient.pid,
.B DBDIR/dhclient.leases~.
.SH SEE ALSO
dhcpd(8), dhcrelay(8), dhclient.conf(5), dhclient.leases(5)
.SH AUTHOR
.B dhclient(8)
has been written for the Internet Software Consortium
by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
Enterprises. To learn more about the Internet Software Consortium,
see
.B http://www.vix.com/isc.
To learn more about Vixie
Enterprises, see
.B http://www.vix.com.
.PP
This client was substantially modified and enhanced by Elliot Poger
for use on Linux while he was working on the MosquitoNet project at
Stanford.
.PP
The current version owes much to Elliot's Linux enhancements, but
was substantially reorganized and partially rewritten by Ted Lemon
so as to use the same networking framework that the Internet Software
Consortium DHCP server uses. Much system-specific configuration code
was moved into a shell script so that as support for more operating
systems is added, it will not be necessary to port and maintain
system-specific configuration code to these operating systems - instead,
the shell script can invoke the native tools to accomplish the same
purpose.
.PP

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,36 @@
send host-name "andare.fugue.com";
send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
send dhcp-lease-time 3600;
supersede domain-name "fugue.com home.vix.com";
prepend domain-name-servers 127.0.0.1;
request subnet-mask, broadcast-address, time-offset, routers,
domain-name, domain-name-servers, host-name;
require subnet-mask, domain-name-servers;
timeout 60;
retry 60;
reboot 10;
select-timeout 5;
initial-interval 2;
script "/etc/dhclient-script";
media "-link0 -link1 -link2", "link0 link1";
reject 192.33.137.209;
alias {
interface "ep0";
fixed-address 192.5.5.213;
option subnet-mask 255.255.255.255;
}
lease {
interface "ep0";
fixed-address 192.33.137.200;
medium "link0 link1";
option host-name "andare.swiftmedia.com";
option subnet-mask 255.255.255.0;
option broadcast-address 192.33.137.255;
option routers 192.33.137.250;
option domain-name-servers 127.0.0.1;
renew 2 2000/1/12 00:00:01;
rebind 2 2000/1/12 00:00:01;
expire 2 2000/1/12 00:00:01;
}

View File

@ -0,0 +1,543 @@
.\" dhclient.conf.5
.\"
.\" Copyright (c) 1997 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of The Internet Software Consortium nor the names
.\" of its contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" This software has been written for the Internet Software Consortium
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
.\" Enterprises. To learn more about the Internet Software Consortium,
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
.\" Enterprises, see ``http://www.vix.com''.
.TH dhclient.conf 5
.SH NAME
dhclient.conf - DHCP client configuration file
.SH DESCRIPTION
The dhclient.conf file contains configuration information for
.IR dhclient,
the Internet Software Consortium DHCP Client.
.PP
The dhclient.conf file is a free-form ASCII text file. It is parsed by
the recursive-descent parser built into dhclient. The file may contain
extra tabs and newlines for formatting purposes. Keywords in the file
are case-insensitive. Comments may be placed anywhere within the
file (except within quotes). Comments begin with the # character and
end at the end of the line.
.PP
The dhclient.conf file can be used to configure the behaviour of the
client in a wide variety of ways: protocol timing, information
requested from the server, information required of the server,
defaults to use if the server does not provide certain information,
values with which to override information provided by the server, or
values to prepend or append to information provided by the server.
The configuration file can also be preinitialized with addresses to
use on networks that don't have DHCP servers.
.SH PROTOCOL TIMING
The timing behaviour of the client need not be configured by the user.
If no timing configuration is provided by the user, a fairly
reasonable timing behaviour will be used by default - one which
results in fairly timely updates without placing an inordinate load on
the server.
.PP
The following statements can be used to adjust the timing behaviour of
the DHCP client if required, however:
.PP
.I The
.B timeout
.I statement
.PP
.B timeout
.I time
.B ;
.PP
The
.I timeout
statement determines the amount of time that must pass between the
time that the client begins to try to determine its address and the
time that it decides that it's not going to be able to contact a
server. By default, this timeout is sixty seconds. After the
timeout has passed, if there are any static leases defined in the
configuration file, or any leases remaining in the lease database that
have not yet expired, the client will loop through these leases
attempting to validate them, and if it finds one that appears to be
valid, it will use that lease's address. If there are no valid
static leases or unexpired leases in the lease database, the client
will restart the protocol after the defined retry interval.
.PP
.I The
.B retry
.I statement
.PP
\fBretry \fItime\fR\fB;\fR
.PP
The
.I retry
statement determines the time that must pass after the client has
determined that there is no DHCP server present before it tries again
to contact a DHCP server. By default, this is five minutes.
.PP
.I The
.B select-timeout
.I statement
.PP
\fBselect-timeout \fItime\fR\fB;\fR
.PP
It is possible (some might say desirable) for there to be more than
one DHCP server serving any given network. In this case, it is
possible that a client may be sent more than one offer in response to
its initial lease discovery message. It may be that one of these
offers is preferable to the other (e.g., one offer may have the
address the client previously used, and the other may not).
.PP
The
.I select-timeout
is the time after the client sends its first lease discovery request
at which it stops waiting for offers from servers, assuming that it
has received at least one such offer. If no offers have been
received by the time the
.I select-timeout
has expired, the client will accept the first offer that arrives.
.PP
By default, the select-timeout is zero seconds - that is, the client
will take the first offer it sees.
.PP
.I The
.B reboot
.I statement
.PP
\fBreboot \fItime\fR\fB;\fR
.PP
When the client is restarted, it first tries to reacquire the last
address it had. This is called the INIT-REBOOT state. If it is
still attached to the same network it was attached to when it last
ran, this is the quickest way to get started. The
.I reboot
statement sets the time that must elapse after the client first tries
to reacquire its old address before it gives up and tries to discover
a new address. By default, the reboot timeout is ten seconds.
.PP
.I The
.B backoff-cutoff
.I statement
.PP
\fBbackoff-cutoff \fItime\fR\fB;\fR
.PP
The client uses an exponential backoff algorithm with some randomness,
so that if many clients try to configure themselves at the same time,
they will not make their requests in lockstep. The
.I backoff-cutoff
statement determines the maximum amount of time that the client is
allowed to back off. It defaults to two minutes.
.PP
.I The
.B initial-interval
.I statement
.PP
\fBinitial-interval \fItime\fR\fB;\fR
.PP
The
.I initial-interval
statement sets the amount of time between the first attempt to reach a
server and the second attempt to reach a server. Each time a message
is sent, the interval between messages is incremented by twice the
current interval multiplied by a random number between zero and one.
If it is greater than the backoff-cutoff amount, it is set to that
amount. It defaults to ten seconds.
.SH LEASE REQUIREMENTS AND REQUESTS
The DHCP protocol allows the client to request that the server send it
specific information, and not send it other information that it is not
prepared to accept. The protocol also allows the client to reject
offers from servers if they don't contain information the client
needs, or if the information provided is not satisfactory.
.PP
There is a variety of data contained in offers that DHCP servers send
to DHCP clients. The data that can be specifically requested is what
are called \fIDHCP Options\fR. DHCP Options are defined in
\fBdhcp-options(5)\fR.
.PP
.I The
.B request
.I statement
.PP
\fBrequest [ \fIoption\fR ] [\fB,\fI ... \fIoption\fR ]\fB;\fR
.PP
The request statement causes the client to request that any server
responding to the client send the client its values for the specified
options. Only the option names should be specified in the request
statement - not option parameters.
.PP
.I The
.B require
.I statement
.PP
\fBrequire [ \fIoption\fR ] [\fB,\fI ... \fIoption ]\fB;\fR
.PP
The require statement lists options that must be sent in order for an
offer to be accepted. Offers that do not contain all the listed
options will be ignored.
.PP
.I The
.B send
.I statement
.PP
\fBsend { [ \fIoption declaration\fR ]
[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
The send statement causes the client to send the specified options to
the server with the specified values. These are full option
declarations as described in \fBdhcp-options(5)\fR. Options that are
always sent in the DHCP protocol should not be specified here, except
that the client can specify a \fBrequested-lease-time\fR option other
than the default requested lease time, which is two hours. The other
obvious use for this statement is to send information to the server
that will allow it to differentiate between this client and other
clients or kinds of clients.
.SH OPTION MODIFIERS
In some cases, a client may receive option data from the server which
is not really appropriate for that client, or may not receive
information that it needs, and for which a useful default value
exists. It may also receive information which is useful, but which
needs to be supplemented with local information. To handle these
needs, several option modifiers are available.
.PP
.I The
.B default
.I statement
.PP
\fBdefault { [ \fIoption declaration\fR ]
[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
If for some set of options the client should use the value supplied by
the server, but needs to use some default value if no value was supplied
by the server, these values can be defined in the
.B default
statement.
.PP
.I The
.B supersede
.I statement
.PP
\fBsupersede { [ \fIoption declaration\fR ]
[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
If for some set of options the client should always use its own value
rather than any value supplied by the server, these values can be
defined in the
.B supersede
statement.
.PP
.I The
.B prepend
.I statement
.PP
\fBprepend { [ \fIoption declaration\fR ]
[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
If for some set of options the client should first a value it
supplies, and then use the values supplied by
the server, if any, these values can be defined in the
.B prepend
statement. The
.B prepend
statement can only be used for options which
allow more than one value to be given.
.PP
.I The
.B append
.I statement
.PP
\fBappend { [ \fIoption declaration\fR ]
[\fB,\fI ... \fIoption declaration\fR ]\fB}\fR
.PP
If for some set of options the client should first a value it
supplies, and then use the values supplied by
the server, if any, these values can be defined in the
.B append
statement. The
.B append
statement can only be used for options which
allow more than one value to be given.
.SH LEASE DECLARATIONS
.PP
.I The
.B lease
.I declaration
.PP
\fBlease {\fR \fIlease-declaration\fR [ ... \fIlease-declaration ] \fB}\fR
.PP
The DHCP client may decide after some period of time (see \fBPROTOCOL
TIMING\fR) decide that it is not going to succeed in contacting a
server. At that time, it consults its own database of old leases and
tests each one that has not yet timed out by pinging the listed router
for that lease to see if that lease could work. It is possible to
define one or more \fIfixed\fR leases in the client configuration file
for networks where there is no DHCP or BOOTP service, so that the
client can still automatically configure its address. This is done
with the
.B lease
statement.
.PP
NOTE: the lease statement is also used in the dhclient.leases file in
order to record leases that have been received from DHCP servers.
Some of the syntax for leases as described below is only needed in the
dhclient.leases file. Such syntax is documented here for
completeness.
.PP
A lease statement consists of the lease keyword, followed by a left
curly brace, followed by one or more lease declaration statements,
followed by a right curly brace. The following lease declarations
are possible:
.PP
\fBbootp;\fR
.PP
The
.B bootp
statement is used to indicate that the lease was acquired using the
BOOTP protocol rather than the DHCP protocol. It is never necessary
to specify this in the client configuration file. The client uses
this syntax in its lease database file.
.PP
\fBinterface\fR \fB"\fR\fIstring\fR\fB";\fR
.PP
The
.B interface
lease statement is used to indicate the interface on which the lease
is valid. If set, this lease will only be tried on a particular
interface. When the client receives a lease from a server, it always
records the interface number on which it received that lease.
If predefined leases are specified in the dhclient.conf file, the
interface should also be specified, although this is not required.
.PP
\fBfixed-address\fR \fIip-address\fR\fB;\fR
.PP
The
.B fixed-address
statement is used to set the ip address of a particular lease. This
is required for all lease statements. The IP address must be
specified as a dotted quad (e.g., 12.34.56.78).
.PP
\fBfilename "\fR\fIstring\fR\fB";\fR
.PP
The
.B filename
statement specifies the name of the boot filename to use. This is
not used by the standard client configuration script, but is included
for completeness.
.PP
\fBserver-name "\fR\fIstring\fR\fB";\fR
.PP
The
.B server-name
statement specifies the name of the boot server name to use. This is
also not used by the standard client configuration script.
.PP
\fBoption\fR \fIoption-declaration\fR\fB;\fR
.PP
The
.B option
statement is used to specify the value of an option supplied by the
server, or, in the case of predefined leases declared in
dhclient.conf, the value that the user wishes the client configuration
script to use if the predefined lease is used.
.PP
\fBscript "\fIscript-name\fB";\fR
.PP
The
.B script
statement is used to specify the pathname of the dhcp client
configuration script. This script is used by the dhcp client to set
each interface's initial configuration prior to requesting an address,
to test the address once it has been offered, and to set the
interface's final configuration once a lease has been acquired. If
no lease is acquired, the script is used to test predefined leases, if
any, and also called once if no valid lease can be identified. For
more information, see
.B dhclient-lease(8).
.PP
\fBmedium "\fImedia setup\fB";\fR
.PP
The
.B medium
statement can be used on systems where network interfaces cannot
automatically determine the type of network to which they are
connected. The media setup string is a system-dependent parameter
which is passed to the dhcp client configuration script when
initializing the interface. On Unix and Unix-like systems, the
argument is passed on the ifconfig command line when configuring te
interface.
.PP
The dhcp client automatically declares this parameter if it used a
media type (see the
.B media
statement) when configuring the interface in order to obtain a lease.
This statement should be used in predefined leases only if the network
interface requires media type configuration.
.PP
\fBrenew\fR \fIdate\fB;\fR
.PP
\fBrebind\fR \fIdate\fB;\fR
.PP
\fBexpire\fR \fIdate\fB;\fR
.PP
The \fBrenew\fR statement defines the time at which the dhcp client
should begin trying to contact its server to renew a lease that it is
using. The \fBrebind\fR statement defines the time at which the dhcp
client should begin to try to contact \fIany\fR dhcp server in order
to renew its lease. The \fBexpire\fR statement defines the time at
which the dhcp client must stop using a lease if it has not been able
to contact a server in order to renew it.
.PP
These declarations are automatically set in leases acquired by the
DHCP client, but must also be configured in predefined leases - a
predefined lease whose expiry time has passed will not be used by the
DHCP client.
.PP
Dates are specified as follows:
.PP
\fI<weekday> <year>\fB/\fI<month>\fB/\fI<day>
<hour>\fB:\fI<minute>\fB:\fI<second>\fR
.PP
The weekday is present to make it easy for a human to tell when a
lease expires - it's specified as a number from zero to six, with zero
being Sunday. When declaring a predefined lease, it can always be
specified as zero. The year is specified with the century, so it
should generally be four digits except for really long leases. The
month is specified as a number starting with 1 for January. The day
of the month is likewise specified starting with 1. The hour is a
number between 0 and 23, the minute a number between 0 and 69, and the
second also a number between 0 and 69.
.SH ALIAS DECLARATIONS
\fBalias { \fI declarations ... \fB}\fR
.PP
Some DHCP clients running TCP/IP roaming protocols may require that in
addition to the lease they may acquire via DHCP, their interface also
be configured with a predefined IP alias so that they can have a
permanent IP address even while roaming. The Internet Software
Consortium DHCP client doesn't support roaming with fixed addresses
directly, but in order to facilitate such experimentation, the dhcp
client can be set up to configure an IP alias using the
.B alias
declaration.
.PP
The alias declaration resembles a lease declaration, except that
options other than the subnet-mask option are ignored by the standard
client configuration script, and expiry times are ignored. A typical
alias declaration includes an interface declaration, a fixed-address
declaration for the IP alias address, and a subnet-mask option
declaration. A medium statement should never be included in an alias
declaration.
.SH OTHER DECLARATIONS
\fBreject \fIip-address\fB;\fR
.PP
The reject statement causes the DHCP client to reject offers from
servers who use the specified address as a server identifier. This
can be used to avoid being configured by rogue or misconfigured dhcp
servers, although it should be a last resort - better to track down
the bad DHCP server and fix it.
.PP
\fBinterface "\fIname\fB" { \fIdeclarations ... \fB }
.PP
A client with more than one network interface may require different
behaviour depending on which interface is being configured. All
timing parameters and declarations other than lease and alias
declarations can be enclosed in an interface declaration, and those
parameters will then be used only for the interface that matches the
specified name. Interfaces for which there is no interface
declaration will use the parameters declared outside of any interface
declaration, or the default settings.
.PP
\fBmedia "\fImedia setup\fB"\fI [ \fB, "\fImedia setup\fB", \fI... ]\fB;\fR
.PP
The
.B media
statement defines one or more media configuration parameters which may
be tried while attempting to acquire an IP address. The dhcp client
will cycle through each media setup string on the list, configuring
the interface using that setup and attempting to boot, and then trying
the next one. This can be used for network interfaces which aren't
capable of sensing the media type unaided - whichever media type
succeeds in getting a request to the server and hearing the reply is
probably right (no guarantees).
.PP
The media setup is only used for the initial phase of address
acquisition (the DHCPDISCOVER and DHCPOFFER packtes). Once an
address has been acquired, the dhcp client will record it in its lease
database and will record the media type used to acquire the address.
Whenever the client tries to renew the lease, it will use that same
media type. The lease must expire before the client will go back to
cycling through media types.
.SH SAMPLE
The following configuration file is used on a laptop running NetBSD
1.3. The laptop has an IP alias of 192.5.5.213, and has one
interface, ep0 (a 3com 3C589C). Booting intervals have been
shortened somewhat from the default, because the client is known to
spend most of its time on networks with little DHCP activity. The
laptop does roam to multiple networks.
.nf
timeout 60;
retry 60;
reboot 10;
select-timeout 5;
initial-interval 2;
reject 192.33.137.209;
interface "ep0" {
send host-name "andare.fugue.com";
send dhcp-client-identifier 1:0:a0:24:ab:fb:9c;
send dhcp-lease-time 3600;
supersede domain-name "fugue.com rc.vix.com home.vix.com";
prepend domain-name-servers 127.0.0.1;
request subnet-mask, broadcast-address, time-offset, routers,
domain-name, domain-name-servers, host-name;
require subnet-mask, domain-name-servers;
script "/etc/dhclient-script";
media "media 10baseT/UTP", "media 10base2/BNC";
}
alias {
interface "ep0";
fixed-address 192.5.5.213;
option subnet-mask 255.255.255.255;
}
.fi
This is a very complicated dhclient.conf file - in general, yours
should be much simpler. In many cases, it's sufficient to just
create an empty dhclient.conf file - the defaults are usually fine.
.SH SEE ALSO
dhcp-options(5), dhclient.leases(5), dhcpd(8), dhcpd.conf(5), RFC2132,
RFC2131.
.SH AUTHOR
.B dhclient(8)
was written by Ted Lemon <mellon@vix.com>
under a contract with Vixie Labs. Funding
for this project was provided by the Internet Software Corporation.
Information about the Internet Software Consortium can be found at
.B http://www.isc.org/isc.

View File

@ -0,0 +1,62 @@
.\" dhclient.conf.5
.\"
.\" Copyright (c) 1997 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of The Internet Software Consortium nor the names
.\" of its contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" This software has been written for the Internet Software Consortium
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
.\" Enterprises. To learn more about the Internet Software Consortium,
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
.\" Enterprises, see ``http://www.vix.com''.
.TH dhclient.leases 5
.SH NAME
dhclient.leases - DHCP client lease database
.SH DESCRIPTION
The Internet Software Consortium DHCP client keeps a persistent
database of leases that it has acquired that are still valid. The
database is a free-form ASCII file containing one valid declaration
per lease. If more than one declaration appears for a given lease,
the last one in the file is used. The file is written as a log, so
this is not an unusual occurrance.
.PP
The format of the lease declarations is described in
.B dhclient.conf(5).
.SH FILES
.B DBDIR/dhclient.leases
.SH SEE ALSO
dhclient(8), dhcp-options(5), dhclient.conf(5), dhcpd(8),
dhcpd.conf(5), RFC2132, RFC2131.
.SH AUTHOR
.B dhclient(8)
was written by Ted Lemon <mellon@vix.com>
under a contract with Vixie Labs. Funding
for this project was provided by the Internet Software Corporation.
Information about the Internet Software Consortium can be found at
.B http://www.isc.org/isc.

View File

@ -0,0 +1,174 @@
#!/bin/sh
if [ x$new_network_number != x ]; then
echo New Network Number: $new_network_number
fi
if [ x$new_broadcast_address != x ]; then
echo New Broadcast Address: $new_broadcast_address
new_broadcast_arg="broadcast $new_broadcast_address"
fi
if [ x$old_broadcast_address != x ]; then
old_broadcast_arg="broadcast $old_broadcast_address"
fi
if [ x$new_subnet_mask != x ]; then
new_netmask_arg="netmask $new_subnet_mask"
fi
if [ x$old_subnet_mask != x ]; then
old_netmask_arg="netmask $old_subnet_mask"
fi
if [ x$alias_subnet_mask != x ]; then
alias_subnet_arg="netmask $alias_subnet_mask"
fi
if [ x$reason = xMEDIUM ]; then
ifconfig $interface $medium
ifconfig $interface inet -alias 0.0.0.0 $medium >/dev/null 2>&1
sleep 1
exit 0
fi
if [ x$reason = xPREINIT ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
ifconfig $interface inet 0.0.0.0 netmask 0.0.0.0 \
broadcast 255.255.255.255 up
exit 0
fi
if [ x$reason = xARPCHECK ] || [ x$reason = xARPSEND ]; then
exit 0;
fi
if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
[ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
if [ x$old_ip_address != x ] && [ x$alias_ip_address != x ] && \
[ x$alias_ip_address != x$old_ip_address ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
if [ x$old_ip_address != x ] && [ x$old_ip_address != x$new_ip_address ]; then
ifconfig $interface inet -alias $old_ip_address $medium
route delete $old_ip_address 127.1 >/dev/null 2>&1
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
if [ "$old_static_routes" != "" ]; then
set $old_static_routes
while [ $# -gt 1 ]; do
route delete $1 $2
shift; shift
done
fi
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' |sh
fi
if [ x$old_ip_address = x ] || [ x$old_ip_address != x$new_ip_address ] || \
[ x$reason = xBOUND ] || [ x$reason = xREBOOT ]; then
ifconfig $interface inet $new_ip_address $new_netmask_arg \
$new_broadcast_arg $medium
route add $new_ip_address 127.1 >/dev/null 2>&1
for router in $new_routers; do
route add default $router >/dev/null 2>&1
done
if [ "$new_static_routes" != "" ]; then
set $new_static_routes
while [ $# -gt 1 ]; do
route add $1 $2
shift; shift
done
fi
fi
if [ x$new_ip_address != x$alias_ip_address ] && [ x$alias_ip_address != x ];
then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
echo search $new_domain_name >/etc/resolv.conf
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf
done
exit 0
fi
if [ x$reason = xEXPIRE ] || [ x$reason = xFAIL ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
if [ x$old_ip_address != x ]; then
ifconfig $interface inet -alias $old_ip_address $medium
route delete $old_ip_address 127.1 >/dev/null 2>&1
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
if [ "$old_static_routes" != "" ]; then
set $old_static_routes
while [ $# -gt 1 ]; do
route delete $1 $2
shift; shift
done
fi
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
|sh >/dev/null 2>&1
fi
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
exit 0
fi
if [ x$reason = xTIMEOUT ]; then
if [ x$alias_ip_address != x ]; then
ifconfig $interface inet -alias $alias_ip_address > /dev/null 2>&1
route delete $alias_ip_address 127.0.0.1 > /dev/null 2>&1
fi
ifconfig $interface inet $new_ip_address $new_netmask_arg \
$new_broadcast_arg $medium
sleep 1
if [ "$new_routers" != "" ]; then
set $new_routers
if ping -q -c 1 -w 1 $1; then
if [ x$new_ip_address != x$alias_ip_address ] && \
[ x$alias_ip_address != x ]; then
ifconfig $interface inet alias $alias_ip_address $alias_subnet_arg
route add $alias_ip_address 127.0.0.1
fi
route add $new_ip_address 127.1 >/dev/null 2>&1
for router in $new_routers; do
route add default $router >/dev/null 2>&1
done
set $new_static_routes
while [ $# -gt 1 ]; do
route add $0 $1
shift; shift
done
echo search $new_domain_name >/etc/resolv.conf.std
for nameserver in $new_domain_name_servers; do
echo nameserver $nameserver >>/etc/resolv.conf.std
done
if [ -f /etc/resolv.conf ]; then
rm -f /etc/resolv.conf
fi
mv /etc/resolv.conf.std /etc/resolv.conf
exit 0
fi
ifconfig $interface inet -alias $new_ip_address $medium
for router in $old_routers; do
route delete default $router >/dev/null 2>&1
done
if [ "$old_static_routes" != "" ]; then
set $old_static_routes
while [ $# -gt 1 ]; do
route delete $1 $2
shift; shift
done
fi
arp -n -a | sed -n -e 's/^.*(\(.*\)) at .*$/arp -n -d \1/p' \
|sh >/dev/null 2>&1
exit 1
fi
exit 0

View File

@ -0,0 +1,329 @@
/* alloc.c
Memory allocation... */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: alloc.c,v 1.13 1997/05/09 07:56:13 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
struct dhcp_packet *dhcp_free_list;
struct packet *packet_free_list;
VOIDPTR dmalloc (size, name)
int size;
char *name;
{
VOIDPTR foo = (VOIDPTR)malloc (size);
if (!foo)
warn ("No memory for %s.", name);
memset (foo, 0, size);
return foo;
}
void dfree (ptr, name)
VOIDPTR ptr;
char *name;
{
if (!ptr) {
warn ("dfree %s: free on null pointer.", name);
return;
}
free (ptr);
}
struct packet *new_packet (name)
char *name;
{
struct packet *rval;
rval = (struct packet *)dmalloc (sizeof (struct packet), name);
return rval;
}
struct dhcp_packet *new_dhcp_packet (name)
char *name;
{
struct dhcp_packet *rval;
rval = (struct dhcp_packet *)dmalloc (sizeof (struct dhcp_packet),
name);
return rval;
}
struct tree *new_tree (name)
char *name;
{
struct tree *rval = dmalloc (sizeof (struct tree), name);
return rval;
}
struct tree_cache *free_tree_caches;
struct tree_cache *new_tree_cache (name)
char *name;
{
struct tree_cache *rval;
if (free_tree_caches) {
rval = free_tree_caches;
free_tree_caches =
(struct tree_cache *)(rval -> value);
} else {
rval = dmalloc (sizeof (struct tree_cache), name);
if (!rval)
error ("unable to allocate tree cache for %s.", name);
}
return rval;
}
struct hash_table *new_hash_table (count, name)
int count;
char *name;
{
struct hash_table *rval = dmalloc (sizeof (struct hash_table)
- (DEFAULT_HASH_SIZE
* sizeof (struct hash_bucket *))
+ (count
* sizeof (struct hash_bucket *)),
name);
rval -> hash_count = count;
return rval;
}
struct hash_bucket *new_hash_bucket (name)
char *name;
{
struct hash_bucket *rval = dmalloc (sizeof (struct hash_bucket), name);
return rval;
}
struct lease *new_leases (n, name)
int n;
char *name;
{
struct lease *rval = dmalloc (n * sizeof (struct lease), name);
return rval;
}
struct lease *new_lease (name)
char *name;
{
struct lease *rval = dmalloc (sizeof (struct lease), name);
return rval;
}
struct subnet *new_subnet (name)
char *name;
{
struct subnet *rval = dmalloc (sizeof (struct subnet), name);
return rval;
}
struct class *new_class (name)
char *name;
{
struct class *rval = dmalloc (sizeof (struct class), name);
return rval;
}
struct shared_network *new_shared_network (name)
char *name;
{
struct shared_network *rval =
dmalloc (sizeof (struct shared_network), name);
return rval;
}
struct group *new_group (name)
char *name;
{
struct group *rval =
dmalloc (sizeof (struct group), name);
return rval;
}
struct protocol *new_protocol (name)
char *name;
{
struct protocol *rval = dmalloc (sizeof (struct protocol), name);
return rval;
}
struct lease_state *free_lease_states;
struct lease_state *new_lease_state (name)
char *name;
{
struct lease_state *rval;
if (free_lease_states) {
rval = free_lease_states;
free_lease_states =
(struct lease_state *)(free_lease_states -> next);
} else {
rval = dmalloc (sizeof (struct lease_state), name);
}
return rval;
}
struct domain_search_list *new_domain_search_list (name)
char *name;
{
struct domain_search_list *rval =
dmalloc (sizeof (struct domain_search_list), name);
return rval;
}
struct name_server *new_name_server (name)
char *name;
{
struct name_server *rval =
dmalloc (sizeof (struct name_server), name);
return rval;
}
void free_name_server (ptr, name)
struct name_server *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_domain_search_list (ptr, name)
struct domain_search_list *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_lease_state (ptr, name)
struct lease_state *ptr;
char *name;
{
ptr -> next = free_lease_states;
free_lease_states = ptr;
}
void free_protocol (ptr, name)
struct protocol *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_group (ptr, name)
struct group *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_shared_network (ptr, name)
struct shared_network *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_class (ptr, name)
struct class *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_subnet (ptr, name)
struct subnet *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_lease (ptr, name)
struct lease *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_hash_bucket (ptr, name)
struct hash_bucket *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_hash_table (ptr, name)
struct hash_table *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_tree_cache (ptr, name)
struct tree_cache *ptr;
char *name;
{
ptr -> value = (unsigned char *)free_tree_caches;
free_tree_caches = ptr;
}
void free_packet (ptr, name)
struct packet *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_dhcp_packet (ptr, name)
struct dhcp_packet *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}
void free_tree (ptr, name)
struct tree *ptr;
char *name;
{
dfree ((VOIDPTR)ptr, name);
}

View File

@ -0,0 +1,386 @@
/* bpf.c
BPF socket interface code, originally contributed by Archie Cobbs. */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: bpf.c,v 1.19 1997/10/20 21:47:13 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <net/bpf.h>
#ifdef NEED_OSF_PFILT_HACKS
#include <net/pfilt.h>
#endif
#include <netinet/in_systm.h>
#include "includes/netinet/ip.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
/* Reinitializes the specified interface after an address change. This
is not required for packet-filter APIs. */
#ifdef USE_BPF_SEND
void if_reinitialize_send (info)
struct interface_info *info;
{
}
#endif
#ifdef USE_BPF_RECEIVE
void if_reinitialize_receive (info)
struct interface_info *info;
{
}
#endif
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
mask. */
int if_register_bpf (info)
struct interface_info *info;
{
int sock;
char filename[50];
int b;
/* Open a BPF device */
for (b = 0; 1; b++) {
#ifndef NO_SNPRINTF
snprintf(filename, sizeof(filename), BPF_FORMAT, b);
#else
sprintf(filename, BPF_FORMAT, b);
#endif
sock = open (filename, O_RDWR, 0);
if (sock < 0) {
if (errno == EBUSY) {
continue;
} else {
error ("Can't find free bpf: %m");
}
} else {
break;
}
}
/* Set the BPF device to point at this interface. */
if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)
error ("Can't attach interface %s to bpf device %s: %m",
info -> name, filename);
return sock;
}
#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */
#ifdef USE_BPF_SEND
void if_register_send (info)
struct interface_info *info;
{
/* If we're using the bpf API for sending and receiving,
we don't need to register this interface twice. */
#ifndef USE_BPF_RECEIVE
info -> wfdesc = if_register_bpf (info, interface);
#else
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on BPF/%s/%s/%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_BPF_SEND */
#ifdef USE_BPF_RECEIVE
/* Packet filter program...
XXX Changes to the filter program may require changes to the constant
offsets used in if_register_send to patch the BPF program! XXX */
struct bpf_insn filter [] = {
/* Make sure this is an IP packet... */
BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),
/* Make sure it's a UDP packet... */
BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
/* Make sure this isn't a fragment... */
BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),
BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
/* Get the IP header length... */
BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),
/* Make sure it's to the right port... */
BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),
BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */
/* If we passed all the tests, ask for the whole packet. */
BPF_STMT(BPF_RET+BPF_K, (u_int)-1),
/* Otherwise, drop it. */
BPF_STMT(BPF_RET+BPF_K, 0),
};
void if_register_receive (info)
struct interface_info *info;
{
int flag = 1;
struct bpf_version v;
u_int32_t addr;
struct bpf_program p;
u_int32_t bits;
/* Open a BPF device and hang it on this interface... */
info -> rfdesc = if_register_bpf (info);
/* Make sure the BPF version is in range... */
if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0)
error ("Can't get BPF version: %m");
if (v.bv_major != BPF_MAJOR_VERSION ||
v.bv_minor < BPF_MINOR_VERSION)
error ("Kernel BPF version out of range - recompile dhcpd!");
/* Set immediate mode so that reads return as soon as a packet
comes in, rather than waiting for the input buffer to fill with
packets. */
if (ioctl (info -> rfdesc, BIOCIMMEDIATE, &flag) < 0)
error ("Can't set immediate mode on bpf device: %m");
#ifdef NEED_OSF_PFILT_HACKS
/* Allow the copyall flag to be set... */
if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
error ("Can't set ALLOWCOPYALL: %m");
/* Clear all the packet filter mode bits first... */
bits = 0;
if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
error ("Can't clear pfilt bits: %m");
/* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */
bits = ENBATCH | ENCOPYALL | ENBPFHDR;
if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
error ("Can't set ENBATCH|ENCOPYALL|ENBPFHDR: %m");
#endif
/* Get the required BPF buffer length from the kernel. */
if (ioctl (info -> rfdesc, BIOCGBLEN, &info -> rbuf_max) < 0)
error ("Can't get bpf buffer length: %m");
info -> rbuf = malloc (info -> rbuf_max);
if (!info -> rbuf)
error ("Can't allocate %d bytes for bpf input buffer.");
info -> rbuf_offset = 0;
info -> rbuf_len = 0;
/* Set up the bpf filter program structure. */
p.bf_len = sizeof filter / sizeof (struct bpf_insn);
p.bf_insns = filter;
/* Patch the server port into the BPF program...
XXX changes to filter program may require changes
to the insn number(s) used below! XXX */
filter [8].k = ntohs (local_port);
if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)
error ("Can't install packet filter program: %m");
if (!quiet_interface_discovery)
note ("Listening on BPF/%s/%s/%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_BPF_RECEIVE */
#ifdef USE_BPF_SEND
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
struct dhcp_packet *raw;
size_t len;
struct in_addr from;
struct sockaddr_in *to;
struct hardware *hto;
{
int bufp = 0;
unsigned char buf [256];
struct iovec iov [2];
/* Assemble the headers... */
assemble_hw_header (interface, buf, &bufp, hto);
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
(unsigned char *)raw, len);
/* Fire it off */
iov [0].iov_base = (char *)buf;
iov [0].iov_len = bufp;
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
return writev(interface -> wfdesc, iov, 2);
}
#endif /* USE_BPF_SEND */
#ifdef USE_BPF_RECEIVE
ssize_t receive_packet (interface, buf, len, from, hfrom)
struct interface_info *interface;
unsigned char *buf;
size_t len;
struct sockaddr_in *from;
struct hardware *hfrom;
{
int length = 0;
int offset = 0;
struct bpf_hdr hdr;
/* All this complexity is because BPF doesn't guarantee
that only one packet will be returned at a time. We're
getting what we deserve, though - this is a terrible abuse
of the BPF interface. Sigh. */
/* Process packets until we get one we can return or until we've
done a read and gotten nothing we can return... */
do {
/* If the buffer is empty, fill it. */
if (interface -> rbuf_offset == interface -> rbuf_len) {
length = read (interface -> rfdesc,
interface -> rbuf,
interface -> rbuf_max);
if (length <= 0)
return length;
interface -> rbuf_offset = 0;
interface -> rbuf_len = length;
}
/* If there isn't room for a whole bpf header, something went
wrong, but we'll ignore it and hope it goes away... XXX */
if (interface -> rbuf_len -
interface -> rbuf_offset < sizeof hdr) {
interface -> rbuf_offset = interface -> rbuf_len;
continue;
}
/* Copy out a bpf header... */
memcpy (&hdr, &interface -> rbuf [interface -> rbuf_offset],
sizeof hdr);
/* If the bpf header plus data doesn't fit in what's left
of the buffer, stick head in sand yet again... */
if (interface -> rbuf_offset +
hdr.bh_hdrlen + hdr.bh_caplen > interface -> rbuf_len) {
interface -> rbuf_offset = interface -> rbuf_len;
continue;
}
/* If the captured data wasn't the whole packet, or if
the packet won't fit in the input buffer, all we
can do is drop it. */
if (hdr.bh_caplen != hdr.bh_datalen) {
interface -> rbuf_offset +=
hdr.bh_hdrlen = hdr.bh_caplen;
continue;
}
/* Skip over the BPF header... */
interface -> rbuf_offset += hdr.bh_hdrlen;
/* Decode the physical header... */
offset = decode_hw_header (interface,
interface -> rbuf,
interface -> rbuf_offset,
hfrom);
/* If a physical layer checksum failed (dunno of any
physical layer that supports this, but WTH), skip this
packet. */
if (offset < 0) {
interface -> rbuf_offset += hdr.bh_caplen;
continue;
}
interface -> rbuf_offset += offset;
hdr.bh_caplen -= offset;
/* Decode the IP and UDP headers... */
offset = decode_udp_ip_header (interface,
interface -> rbuf,
interface -> rbuf_offset,
from,
(unsigned char *)0,
hdr.bh_caplen);
/* If the IP or UDP checksum was bad, skip the packet... */
if (offset < 0) {
interface -> rbuf_offset += hdr.bh_caplen;
continue;
}
interface -> rbuf_offset += offset;
hdr.bh_caplen -= offset;
/* If there's not enough room to stash the packet data,
we have to skip it (this shouldn't happen in real
life, though). */
if (hdr.bh_caplen > len) {
interface -> rbuf_offset += hdr.bh_caplen;
continue;
}
/* Copy out the data in the packet... */
memcpy (buf, interface -> rbuf + interface -> rbuf_offset,
hdr.bh_caplen);
interface -> rbuf_offset += hdr.bh_caplen;
return hdr.bh_caplen;
} while (!length);
return 0;
}
#endif

View File

@ -0,0 +1,548 @@
/* conflex.c
Lexical scanner for dhcpd config file... */
/*
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: conflex.c,v 1.29 1997/10/29 18:32:53 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "dhctoken.h"
#include <ctype.h>
int lexline;
int lexchar;
char *token_line;
char *prev_line;
char *cur_line;
char *tlname;
int eol_token;
static char line1 [81];
static char line2 [81];
static int lpos;
static int line;
static int tlpos;
static int tline;
static int token;
static int ugflag;
static char *tval;
static char tokbuf [1500];
#ifdef OLD_LEXER
char comments [4096];
int comment_index;
#endif
static int get_char PROTO ((FILE *));
static int get_token PROTO ((FILE *));
static void skip_to_eol PROTO ((FILE *));
static int read_string PROTO ((FILE *));
static int read_number PROTO ((int, FILE *));
static int read_num_or_name PROTO ((int, FILE *));
static int intern PROTO ((char *, int));
void new_parse (name)
char *name;
{
tlname = name;
lpos = line = 1;
cur_line = line1;
prev_line = line2;
token_line = cur_line;
cur_line [0] = prev_line [0] = 0;
warnings_occurred = 0;
}
static int get_char (cfile)
FILE *cfile;
{
int c = getc (cfile);
if (!ugflag) {
if (c == EOL) {
if (cur_line == line1) {
cur_line = line2;
prev_line = line1;
} else {
cur_line = line2;
prev_line = line1;
}
line++;
lpos = 1;
cur_line [0] = 0;
} else if (c != EOF) {
if (lpos <= 81) {
cur_line [lpos - 1] = c;
cur_line [lpos] = 0;
}
lpos++;
}
} else
ugflag = 0;
return c;
}
static int get_token (cfile)
FILE *cfile;
{
int c;
int ttok;
static char tb [2];
int l, p, u;
do {
l = line;
p = lpos;
u = ugflag;
c = get_char (cfile);
#ifdef OLD_LEXER
if (c == '\n' && p == 1 && !u
&& comment_index < sizeof comments)
comments [comment_index++] = '\n';
#endif
if (!(c == '\n' && eol_token) && isascii (c) && isspace (c))
continue;
if (c == '#') {
#ifdef OLD_LEXER
if (comment_index < sizeof comments)
comments [comment_index++] = '#';
#endif
skip_to_eol (cfile);
continue;
}
if (c == '"') {
lexline = l;
lexchar = p;
ttok = read_string (cfile);
break;
}
if ((isascii (c) && isdigit (c)) || c == '-') {
lexline = l;
lexchar = p;
ttok = read_number (c, cfile);
break;
} else if (isascii (c) && isalpha (c)) {
lexline = l;
lexchar = p;
ttok = read_num_or_name (c, cfile);
break;
} else {
lexline = l;
lexchar = p;
tb [0] = c;
tb [1] = 0;
tval = tb;
ttok = c;
break;
}
} while (1);
return ttok;
}
int next_token (rval, cfile)
char **rval;
FILE *cfile;
{
int rv;
if (token) {
if (lexline != tline)
token_line = cur_line;
lexchar = tlpos;
lexline = tline;
rv = token;
token = 0;
} else {
rv = get_token (cfile);
token_line = cur_line;
}
if (rval)
*rval = tval;
#ifdef DEBUG_TOKENS
fprintf (stderr, "%s:%d ", tval, rv);
#endif
return rv;
}
int peek_token (rval, cfile)
char **rval;
FILE *cfile;
{
int x;
if (!token) {
tlpos = lexchar;
tline = lexline;
token = get_token (cfile);
if (lexline != tline)
token_line = prev_line;
x = lexchar; lexchar = tlpos; tlpos = x;
x = lexline; lexline = tline; tline = x;
}
if (rval)
*rval = tval;
#ifdef DEBUG_TOKENS
fprintf (stderr, "(%s:%d) ", tval, token);
#endif
return token;
}
static void skip_to_eol (cfile)
FILE *cfile;
{
int c;
do {
c = get_char (cfile);
if (c == EOF)
return;
#ifdef OLD_LEXER
if (comment_index < sizeof (comments))
comments [comment_index++] = c;
#endif
if (c == EOL) {
return;
}
} while (1);
}
static int read_string (cfile)
FILE *cfile;
{
int i;
int bs = 0;
int c;
for (i = 0; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (c == EOF) {
parse_warn ("eof in string constant");
break;
}
if (bs) {
bs = 0;
tokbuf [i] = c;
} else if (c == '\\')
bs = 1;
else if (c == '"')
break;
else
tokbuf [i] = c;
}
/* Normally, I'd feel guilty about this, but we're talking about
strings that'll fit in a DHCP packet here... */
if (i == sizeof tokbuf) {
parse_warn ("string constant larger than internal buffer");
--i;
}
tokbuf [i] = 0;
tval = tokbuf;
return STRING;
}
static int read_number (c, cfile)
int c;
FILE *cfile;
{
int seenx = 0;
int i = 0;
int token = NUMBER;
tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (!seenx && c == 'x') {
seenx = 1;
#ifndef OLD_LEXER
} else if (isascii (c) && !isxdigit (c) &&
(c == '-' || c == '_' || isalpha (c))) {
token = NAME;
} else if (isascii (c) && !isdigit (c) && isxdigit (c)) {
token = NUMBER_OR_NAME;
#endif
} else if (!isascii (c) || !isxdigit (c)) {
ungetc (c, cfile);
ugflag = 1;
break;
}
tokbuf [i] = c;
}
if (i == sizeof tokbuf) {
parse_warn ("numeric token larger than internal buffer");
--i;
}
tokbuf [i] = 0;
tval = tokbuf;
return token;
}
static int read_num_or_name (c, cfile)
int c;
FILE *cfile;
{
int i = 0;
int rv = NUMBER_OR_NAME;
tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (!isascii (c) ||
(c != '-' && c != '_' && !isalnum (c))) {
ungetc (c, cfile);
ugflag = 1;
break;
}
if (!isxdigit (c))
rv = NAME;
tokbuf [i] = c;
}
if (i == sizeof tokbuf) {
parse_warn ("token larger than internal buffer");
--i;
}
tokbuf [i] = 0;
tval = tokbuf;
return intern (tval, rv);
}
static int intern (atom, dfv)
char *atom;
int dfv;
{
if (!isascii (atom [0]))
return dfv;
switch (tolower (atom [0])) {
case 'a':
if (!strcasecmp (atom + 1, "ppend"))
return APPEND;
if (!strcasecmp (atom + 1, "llow"))
return ALLOW;
if (!strcasecmp (atom + 1, "lias"))
return ALIAS;
if (!strcasecmp (atom + 1, "bandoned"))
return ABANDONED;
break;
case 'b':
if (!strcasecmp (atom + 1, "ackoff-cutoff"))
return BACKOFF_CUTOFF;
if (!strcasecmp (atom + 1, "ootp"))
return BOOTP;
if (!strcasecmp (atom + 1, "ooting"))
return BOOTING;
if (!strcasecmp (atom + 1, "oot-unknown-clients"))
return BOOT_UNKNOWN_CLIENTS;
case 'c':
if (!strcasecmp (atom + 1, "lass"))
return CLASS;
if (!strcasecmp (atom + 1, "iaddr"))
return CIADDR;
if (!strcasecmp (atom + 1, "lient-identifier"))
return CLIENT_IDENTIFIER;
if (!strcasecmp (atom + 1, "lient-hostname"))
return CLIENT_HOSTNAME;
break;
case 'd':
if (!strcasecmp (atom + 1, "omain"))
return DOMAIN;
if (!strcasecmp (atom + 1, "eny"))
return DENY;
if (!strncasecmp (atom + 1, "efault", 6)) {
if (!atom [7])
return DEFAULT;
if (!strcasecmp (atom + 7, "-lease-time"))
return DEFAULT_LEASE_TIME;
break;
}
if (!strncasecmp (atom + 1, "ynamic-bootp", 12)) {
if (!atom [13])
return DYNAMIC_BOOTP;
if (!strcasecmp (atom + 13, "-lease-cutoff"))
return DYNAMIC_BOOTP_LEASE_CUTOFF;
if (!strcasecmp (atom + 13, "-lease-length"))
return DYNAMIC_BOOTP_LEASE_LENGTH;
break;
}
break;
case 'e':
if (!strcasecmp (atom + 1, "thernet"))
return ETHERNET;
if (!strcasecmp (atom + 1, "nds"))
return ENDS;
if (!strcasecmp (atom + 1, "xpire"))
return EXPIRE;
break;
case 'f':
if (!strcasecmp (atom + 1, "ilename"))
return FILENAME;
if (!strcasecmp (atom + 1, "ixed-address"))
return FIXED_ADDR;
break;
case 'g':
if (!strcasecmp (atom + 1, "iaddr"))
return GIADDR;
if (!strcasecmp (atom + 1, "roup"))
return GROUP;
if (!strcasecmp (atom + 1, "et-lease-hostnames"))
return GET_LEASE_HOSTNAMES;
break;
case 'h':
if (!strcasecmp (atom + 1, "ost"))
return HOST;
if (!strcasecmp (atom + 1, "ardware"))
return HARDWARE;
if (!strcasecmp (atom + 1, "ostname"))
return HOSTNAME;
break;
case 'i':
if (!strcasecmp (atom + 1, "nitial-interval"))
return INITIAL_INTERVAL;
if (!strcasecmp (atom + 1, "nterface"))
return INTERFACE;
break;
case 'l':
if (!strcasecmp (atom + 1, "ease"))
return LEASE;
break;
case 'm':
if (!strcasecmp (atom + 1, "ax-lease-time"))
return MAX_LEASE_TIME;
if (!strncasecmp (atom + 1, "edi", 3)) {
if (!strcasecmp (atom + 4, "a"))
return MEDIA;
if (!strcasecmp (atom + 4, "um"))
return MEDIUM;
break;
}
break;
case 'n':
if (!strcasecmp (atom + 1, "ameserver"))
return NAMESERVER;
if (!strcasecmp (atom + 1, "etmask"))
return NETMASK;
if (!strcasecmp (atom + 1, "ext-server"))
return NEXT_SERVER;
break;
case 'o':
if (!strcasecmp (atom + 1, "ption"))
return OPTION;
if (!strcasecmp (atom + 1, "ne-lease-per-client"))
return ONE_LEASE_PER_CLIENT;
break;
case 'p':
if (!strcasecmp (atom + 1, "repend"))
return PREPEND;
if (!strcasecmp (atom + 1, "acket"))
return PACKET;
break;
case 'r':
if (!strcasecmp (atom + 1, "ange"))
return RANGE;
if (!strcasecmp (atom + 1, "equest"))
return REQUEST;
if (!strcasecmp (atom + 1, "equire"))
return REQUIRE;
if (!strcasecmp (atom + 1, "etry"))
return RETRY;
if (!strcasecmp (atom + 1, "enew"))
return RENEW;
if (!strcasecmp (atom + 1, "ebind"))
return REBIND;
if (!strcasecmp (atom + 1, "eboot"))
return REBOOT;
if (!strcasecmp (atom + 1, "eject"))
return REJECT;
break;
case 's':
if (!strcasecmp (atom + 1, "earch"))
return SEARCH;
if (!strcasecmp (atom + 1, "tarts"))
return STARTS;
if (!strcasecmp (atom + 1, "iaddr"))
return SIADDR;
if (!strcasecmp (atom + 1, "ubnet"))
return SUBNET;
if (!strcasecmp (atom + 1, "hared-network"))
return SHARED_NETWORK;
if (!strcasecmp (atom + 1, "erver-name"))
return SERVER_NAME;
if (!strcasecmp (atom + 1, "erver-identifier"))
return SERVER_IDENTIFIER;
if (!strcasecmp (atom + 1, "elect-timeout"))
return SELECT_TIMEOUT;
if (!strcasecmp (atom + 1, "end"))
return SEND;
if (!strcasecmp (atom + 1, "cript"))
return SCRIPT;
if (!strcasecmp (atom + 1, "upersede"))
return SUPERSEDE;
break;
case 't':
if (!strcasecmp (atom + 1, "imestamp"))
return TIMESTAMP;
if (!strcasecmp (atom + 1, "imeout"))
return TIMEOUT;
if (!strcasecmp (atom + 1, "oken-ring"))
return TOKEN_RING;
break;
case 'u':
if (!strcasecmp (atom + 1, "id"))
return UID;
if (!strcasecmp (atom + 1, "ser-class"))
return USER_CLASS;
if (!strcasecmp (atom + 1, "se-host-decl-names"))
return USE_HOST_DECL_NAMES;
if (!strcasecmp (atom + 1, "nknown-clients"))
return UNKNOWN_CLIENTS;
break;
case 'v':
if (!strcasecmp (atom + 1, "endor-class"))
return VENDOR_CLASS;
break;
case 'y':
if (!strcasecmp (atom + 1, "iaddr"))
return YIADDR;
break;
}
return dfv;
}

View File

@ -0,0 +1,118 @@
/* convert.c
Safe copying of option values into and out of the option buffer, which
can't be assumed to be aligned. */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: convert.c,v 1.4.2.1 1998/06/25 21:11:28 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
u_int32_t getULong (buf)
unsigned char *buf;
{
unsigned long ibuf;
memcpy (&ibuf, buf, sizeof (u_int32_t));
return ntohl (ibuf);
}
int32_t getLong (buf)
unsigned char *buf;
{
long ibuf;
memcpy (&ibuf, buf, sizeof (int32_t));
return ntohl (ibuf);
}
u_int16_t getUShort (buf)
unsigned char *buf;
{
unsigned short ibuf;
memcpy (&ibuf, buf, sizeof (u_int16_t));
return ntohs (ibuf);
}
int16_t getShort (buf)
unsigned char *buf;
{
short ibuf;
memcpy (&ibuf, buf, sizeof (int16_t));
return ntohs (ibuf);
}
void putULong (obuf, val)
unsigned char *obuf;
u_int32_t val;
{
u_int32_t tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putLong (obuf, val)
unsigned char *obuf;
int32_t val;
{
int32_t tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putUShort (obuf, val)
unsigned char *obuf;
unsigned int val;
{
u_int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putShort (obuf, val)
unsigned char *obuf;
int val;
{
int16_t tmp = htons (val);
memcpy (obuf, &tmp, sizeof tmp);
}

View File

@ -0,0 +1,451 @@
.\" dhcp-options.5
.\"
.\" Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of The Internet Software Consortium nor the names
.\" of its contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
.\" DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
.\" CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" This software has been written for the Internet Software Consortium
.\" by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
.\" Enterprises. To learn more about the Internet Software Consortium,
.\" see ``http://www.isc.org/isc''. To learn more about Vixie
.\" Enterprises, see ``http://www.vix.com''.
.TH dhcpd-options 5
.SH NAME
dhcp-options - Dynamic Host Configuration Protocol options
.SH DESCRIPTION
The Dynamic Host Configuration protocol allows the client to receive
.B options
from the DHCP server describing the network configuration and various
services that are available on the network. When configuring
.B dhcpd(8)
or
.B dhclient(8) ,
options must often be declared. The syntax for declaring options,
and the names and formats of the options that can be declared, are
documented here.
.SH REFERENCE: OPTION STATEMENTS
.PP
DHCP \fIoption\fR statements always start with the \fIoption\fR
keyword, followed by an option name, followed by option data. The
option names and data formats are described below. It is not
necessary to exhaustively specify all DHCP options - only those
options which are needed by clients must be specified.
.PP
Option data comes in a variety of formats, as defined below:
.PP
The
.B ip-address
data type can be entered either as an explicit IP
address (e.g., 239.254.197.10) or as a domain name (e.g.,
haagen.isc.org). When entering a domain name, be sure that that
domain name resolves to a single IP address.
.PP
The
.B int32
data type specifies a signed 32-bit integer. The
.B uint32
data type specifies an unsigned 32-bit integer. The
.B int16
and
.B uint16
data types specify signed and unsigned 16-bit integers. The
.B int8
and
.B uint8
data types specify signed and unsigned 8-bit integers.
Unsigned 8-bit integers are also sometimes referred to as octets.
.PP
The
.B string
data type specifies an NVT ASCII string, which must be
enclosed in double quotes - for example, to specify a domain-name
option, the syntax would be
.nf
.sp 1
option domain-name "isc.org";
.fi
.PP
The
.B flag
data type specifies a boolean value. Booleans can be either true or
false (or on or off, if that makes more sense to you).
.PP
The
.B data-string
data type specifies either an NVT ASCII string
enclosed in double quotes, or a series of octets specified in
hexadecimal, seperated by colons. For example:
.nf
.sp 1
option client-identifier "CLIENT-FOO";
or
option client-identifier 43:4c:49:45:54:2d:46:4f:4f;
.fi
.PP
The documentation for the various options mentioned below is taken
from the latest IETF draft document on DHCP options. Options which
are not listed by name may be defined by the name option-\fInnn\fR,
where \fInnn\fI is the decimal number of the option code. These
options may be followed either by a string, enclosed in quotes, or by
a series of octets, expressed as two-digit hexadecimal numbers seperated
by colons. For example:
.PP
.nf
option option-133 "my-option-133-text";
option option-129 1:54:c9:2b:47;
.fi
.PP
Because dhcpd does not know the format of these undefined option codes,
no checking is done to ensure the correctness of the entered data.
.PP
The standard options are:
.PP
\fBoption subnet-mask\fR \fIip-address\fR\fB;\fR
.PP
The subnet mask option specifies the client's subnet mask as per RFC
950. If no subnet mask option is provided anywhere in scope, as a
last resort dhcpd will use the subnet mask from the subnet declaration
for the network on which an address is being assigned. However,
.I any
subnet-mask option declaration that is in scope for the address being
assigned will override the subnet mask specified in the subnet
declaration.
.PP
\fBoption time-offset\fR \fIint32\fR\fB;\fR
.PP
The time-offset option specifies the offset of the client's subnet in
seconds from Coordinated Universal Time (UTC).
.PP
\fBoption routers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The routers option specifies a list of IP addresses for routers on the
client's subnet. Routers should be listed in order of preference.
.PP
\fBoption time-servers\fR \fIip-address [, \fIip-address\fR ... ]\fB;\fR
.PP
The time-server option specifies a list of RFC 868 time servers
available to the client. Servers should be listed in order of
preference.
.PP
\fBoption\fR \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ];
.PP
The ien116-name-servers option specifies a list of IEN 116 name servers
available to the client. Servers should be listed in order of
preference.
.PP
\fBoption\fR \fBdomain-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The domain-name-servers option specifies a list of Domain Name System
(STD 13, RFC 1035) name servers available to the client. Servers
should be listed in order of preference.
.PP
\fBoption\fR \fBlog-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The log-server option specifies a list of MIT-LCS UDP log servers
available to the client. Servers should be listed in order of
preference.
.PP
\fBoption\fR \fBcookie-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The cookie server option specifies a list of RFC 865 cookie
servers available to the client. Servers should be listed in order
of preference.
.PP
\fBoption\fR \fBlpr-servers\fR \fIip-address \fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The LPR server option specifies a list of RFC 1179 line printer
servers available to the client. Servers should be listed in order
of preference.
.PP
\fBoption\fR \fBimpress-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The impress-server option specifies a list of Imagen Impress servers
available to the client. Servers should be listed in order of
preference.
.PP
\fBoption\fR \fBresource-location-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
This option specifies a list of RFC 887 Resource Location
servers available to the client. Servers should be listed in order
of preference.
.PP
\fBoption\fR \fBhost-name\fR \fIstring\fR\fB;\fR
.PP
This option specifies the name of the client. The name may or may
not be qualified with the local domain name (it is preferable to use
the domain-name option to specify the domain name). See RFC 1035 for
character set restrictions.
.PP
\fBoption\fR \fBboot-size\fR \fIuint16\fR\fB;\fR
.PP
This option specifies the length in 512-octet blocks of the default
boot image for the client.
.PP
\fBoption\fR \fBmerit-dump\fR \fIstring\fR\fB;\fR
.PP
This option specifies the path-name of a file to which the client's
core image should be dumped in the event the client crashes. The
path is formatted as a character string consisting of characters from
the NVT ASCII character set.
.PP
\fBoption\fR \fBdomain-name\fR \fIstring\fR\fB;\fR
.PP
This option specifies the domain name that client should use when
resolving hostnames via the Domain Name System.
.PP
\fBoption\fR \fBswap-server\fR \fIip-address\fR\fB;\fR
.PP
This specifies the IP address of the client's swap server.
.PP
\fBoption\fR \fBroot-path\fR \fIstring\fB;\fR\fR
.PP
This option specifies the path-name that contains the client's root
disk. The path is formatted as a character string consisting of
characters from the NVT ASCII character set.
.PP
\fBoption\fR \fBip-forwarding\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether the client should configure its IP
layer for packet forwarding. A value of 0 means disable IP
forwarding, and a value of 1 means enable IP forwarding.
.PP
\fBoption\fR \fBnon-local-source-routing\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether the client should configure its IP
layer to allow forwarding of datagrams with non-local source routes
(see Section 3.3.5 of [4] for a discussion of this topic). A value
of 0 means disallow forwarding of such datagrams, and a value of 1
means allow forwarding.
.PP
\fBoption\fR \fBpolicy-filter\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR ... ]\fB;\fR
.PP
This option specifies policy filters for non-local source routing.
The filters consist of a list of IP addresses and masks which specify
destination/mask pairs with which to filter incoming source routes.
.PP
Any source routed datagram whose next-hop address does not match one
of the filters should be discarded by the client.
.PP
See STD 3 (RFC1122) for further information.
.PP
\fBoption\fR \fBmax-dgram-reassembly\fR \fIuint16\fR\fB;\fR
.PP
This option specifies the maximum size datagram that the client
should be prepared to reassemble. The minimum value legal value is
576.
.PP
\fBoption\fR \fBdefault-ip-ttl\fR \fIuint8;\fR
.PP
This option specifies the default time-to-live that the client should
use on outgoing datagrams.
.PP
\fBoption\fR \fBpath-mtu-aging-timeout\fR \fIuint32\fR\fB;\fR
.PP
This option specifies the timeout (in seconds) to use when aging Path
MTU values discovered by the mechanism defined in RFC 1191.
.PP
\fBoption\fR \fBpath-mtu-plateau-table\fR \fIuint16\fR [\fB,\fR \fIuint16\fR ... ]\fB;\fR
.PP
This option specifies a table of MTU sizes to use when performing
Path MTU Discovery as defined in RFC 1191. The table is formatted as
a list of 16-bit unsigned integers, ordered from smallest to largest.
The minimum MTU value cannot be smaller than 68.
.PP
\fBoption\fR \fBinterface-mtu\fR \fIuint16\fR\fB;\fR
.PP
This option specifies the MTU to use on this interface. The minimum
legal value for the MTU is 68.
.PP
\fBoption\fR \fBall-subnets-local\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether or not the client may assume that all
subnets of the IP network to which the client is connected use the
same MTU as the subnet of that network to which the client is
directly connected. A value of 1 indicates that all subnets share
the same MTU. A value of 0 means that the client should assume that
some subnets of the directly connected network may have smaller MTUs.
.PP
\fBoption\fR \fBbroadcast-address\fR \fIip-address\fR\fB;\fR
.PP
This option specifies the broadcast address in use on the client's
subnet. Legal values for broadcast addresses are specified in
section 3.2.1.3 of STD 3 (RFC1122).
.PP
\fBoption\fR \fBperform-mask-discovery\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether or not the client should perform subnet
mask discovery using ICMP. A value of 0 indicates that the client
should not perform mask discovery. A value of 1 means that the
client should perform mask discovery.
.PP
\fBoption\fR \fBmask-supplier\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether or not the client should respond to
subnet mask requests using ICMP. A value of 0 indicates that the
client should not respond. A value of 1 means that the client should
respond.
.PP
\fBoption\fR \fBrouter-discovery\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether or not the client should solicit
routers using the Router Discovery mechanism defined in RFC 1256.
A value of 0 indicates that the client should not perform
router discovery. A value of 1 means that the client should perform
router discovery.
.PP
\fBoption\fR \fBrouter-solicitation-address\fR \fIip-address\fR\fB;\fR
.PP
This option specifies the address to which the client should transmit
router solicitation requests.
.PP
\fBoption\fR \fBstatic-routes\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR ... ]\fB;\fR
.PP
This option specifies a list of static routes that the client should
install in its routing cache. If multiple routes to the same
destination are specified, they are listed in descending order of
priority.
.PP
The routes consist of a list of IP address pairs. The first address
is the destination address, and the second address is the router for
the destination.
.PP
The default route (0.0.0.0) is an illegal destination for a static
route. To specify the default route, use the
.B routers
option.
.PP
\fBoption\fR \fBtrailer-encapsulation\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether or not the client should negotiate the
use of trailers (RFC 893 [14]) when using the ARP protocol. A value
of 0 indicates that the client should not attempt to use trailers. A
value of 1 means that the client should attempt to use trailers.
.PP
\fBoption\fR \fBarp-cache-timeout\fR \fIuint32\fR\fB;\fR
.PP
This option specifies the timeout in seconds for ARP cache entries.
.PP
\fBoption\fR \fBieee802-3-encapsulation\fR \fIflag\fR\fB;\fR
.PP
This option specifies whether or not the client should use Ethernet
Version 2 (RFC 894) or IEEE 802.3 (RFC 1042) encapsulation if the
interface is an Ethernet. A value of 0 indicates that the client
should use RFC 894 encapsulation. A value of 1 means that the client
should use RFC 1042 encapsulation.
.PP
\fBoption\fR \fBdefault-tcp-ttl\fR \fIuint8\fR\fB;\fR
.PP
This option specifies the default TTL that the client should use when
sending TCP segments. The minimum value is 1.
.PP
\fBoption\fR \fBtcp-keepalive-interval\fR \fIuint32\fR\fB;\fR
.PP
This option specifies the interval (in seconds) that the client TCP
should wait before sending a keepalive message on a TCP connection.
The time is specified as a 32-bit unsigned integer. A value of zero
indicates that the client should not generate keepalive messages on
connections unless specifically requested by an application.
.PP
\fBoption\fR \fBtcp-keepalive-garbage\fR \fIflag\fR\fB;\fR
.PP
This option specifies the whether or not the client should send TCP
keepalive messages with a octet of garbage for compatibility with
older implementations. A value of 0 indicates that a garbage octet
should not be sent. A value of 1 indicates that a garbage octet
should be sent.
.PP
\fBoption\fR \fBnis-domain\fR \fIstring\fR\fB;\fR
.PP
This option specifies the name of the client's NIS (Sun Network
Information Services) domain. The domain is formatted as a character
string consisting of characters from the NVT ASCII character set.
.PP
\fBoption\fR \fBnis-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
This option specifies a list of IP addresses indicating NIS servers
available to the client. Servers should be listed in order of
preference.
.PP
\fBoption\fR \fBntp-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
This option specifies a list of IP addresses indicating NTP (RFC 1035)
servers available to the client. Servers should be listed in order
of preference.
.PP
\fBoption\fR \fBnetbios-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The NetBIOS name server (NBNS) option specifies a list of RFC
1001/1002 NBNS name servers listed in order of preference.
.PP
\fBoption\fR \fBnetbios-dd-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
The NetBIOS datagram distribution server (NBDD) option specifies a
list of RFC 1001/1002 NBDD servers listed in order of preference.
.PP
\fBoption\fR \fBnetbios-node-type\fR \fIuint8\fR\fB;\fR
.PP
The NetBIOS node type option allows NetBIOS over TCP/IP clients which
are configurable to be configured as described in RFC 1001/1002. The
value is specified as a single octet which identifies the client type.
A value of 1 corresponds to a NetBIOS B-node; a value of 2 corresponds
to a P-node; a value of 4 corresponds to an M-node; a value of 8
corresponds to an H-node.
.PP
\fBoption\fR \fBnetbios-scope\fR \fIstring\fR\fB;\fR
.PP
The NetBIOS scope option specifies the NetBIOS over TCP/IP scope
parameter for the client as specified in RFC 1001/1002. See RFC1001,
RFC1002, and RFC1035 for character-set restrictions.
.PP
\fBoption\fR \fBfont-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
This option specifies a list of X Window System Font servers available
to the client. Servers should be listed in order of preference.
.PP
\fBoption\fR \fBx-display-manager\fR \fIip-address\fR [\fB,\fR \fIip-address\fR ... ]\fB;\fR
.PP
This option specifies a list of systems that are running the X Window
System Display Manager and are available to the client. Addresses
should be listed in order of preference.
.PP
\fBoption\fR \fBdhcp-client-identifier\fR \fIdata-string\fR\fB;\fR
.PP
This option can be used to specify the a DHCP client identifier in a
host declaration, so that dhcpd can find the host record by matching
against the client identifier.
.SH SEE ALSO
dhcpd.conf(5), dhcpd.leases(5), dhclient.conf(5), dhcpd(8),
dhclient(8), RFC2132, RFC2131.
.SH AUTHOR
.B dhcpd(8)
was written by Ted Lemon <mellon@vix.com>
under a contract with Vixie Labs. Funding
for this project was provided by the Internet Software Corporation.
Information about the Internet Software Consortium can be found at
.B http://www.isc.org/isc.

View File

@ -0,0 +1,750 @@
/* dispatch.c
Network input dispatcher... */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: dispatch.c,v 1.47.2.2 1998/06/25 21:11:28 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/ioctl.h>
struct interface_info *interfaces, *dummy_interfaces;
struct protocol *protocols;
struct timeout *timeouts;
static struct timeout *free_timeouts;
static int interfaces_invalidated;
void (*bootp_packet_handler) PROTO ((struct interface_info *,
struct dhcp_packet *, int, unsigned int,
struct iaddr, struct hardware *));
static void got_one PROTO ((struct protocol *));
int quiet_interface_discovery;
/* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
For each interface that's of type INET and not the loopback interface,
register that interface with the network I/O software, figure out what
subnet it's on, and add it to the list of interfaces. */
void discover_interfaces (state)
int state;
{
struct interface_info *tmp;
struct interface_info *last, *next;
char buf [8192];
struct ifconf ic;
struct ifreq ifr;
int i;
int sock;
int address_count = 0;
struct subnet *subnet;
struct shared_network *share;
struct sockaddr_in foo;
int ir;
#ifdef ALIAS_NAMES_PERMUTED
char *s;
#endif
#ifdef USE_FALLBACK
static struct shared_network fallback_network;
#endif
/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
error ("Can't create addrlist socket");
/* Get the interface configuration information... */
ic.ifc_len = sizeof buf;
ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
i = ioctl(sock, SIOCGIFCONF, &ic);
if (i < 0)
error ("ioctl: SIOCGIFCONF: %m");
/* If we already have a list of interfaces, and we're running as
a DHCP server, the interfaces were requested. */
if (interfaces && (state == DISCOVER_SERVER ||
state == DISCOVER_RELAY ||
state == DISCOVER_REQUESTED))
ir = 0;
else if (state == DISCOVER_UNCONFIGURED)
ir = INTERFACE_REQUESTED | INTERFACE_AUTOMATIC;
else
ir = INTERFACE_REQUESTED;
/* Cycle through the list of interfaces looking for IP addresses.
Go through twice; once to count the number of addresses, and a
second time to copy them into an array of addresses. */
for (i = 0; i < ic.ifc_len;) {
struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
#ifdef HAVE_SA_LEN
if (ifp -> ifr_addr.sa_len)
i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
else
#endif
i += sizeof *ifp;
#ifdef ALIAS_NAMES_PERMUTED
if ((s = strrchr (ifp -> ifr_name, ':'))) {
*s = 0;
}
#endif
#ifdef SKIP_DUMMY_INTERFACES
if (!strncmp (ifp -> ifr_name, "dummy", 5))
continue;
#endif
/* See if this is the sort of interface we want to
deal with. */
strcpy (ifr.ifr_name, ifp -> ifr_name);
if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
error ("Can't get interface flags for %s: %m",
ifr.ifr_name);
/* Skip loopback, point-to-point and down interfaces,
except don't skip down interfaces if we're trying to
get a list of configurable interfaces. */
if ((ifr.ifr_flags & IFF_LOOPBACK) ||
#ifdef IFF_POINTOPOINT
(ifr.ifr_flags & IFF_POINTOPOINT) ||
#endif
(!(ifr.ifr_flags & IFF_UP) &&
state != DISCOVER_UNCONFIGURED))
continue;
/* See if we've seen an interface that matches this one. */
for (tmp = interfaces; tmp; tmp = tmp -> next)
if (!strcmp (tmp -> name, ifp -> ifr_name))
break;
/* If there isn't already an interface by this name,
allocate one. */
if (!tmp) {
tmp = ((struct interface_info *)
dmalloc (sizeof *tmp, "discover_interfaces"));
if (!tmp)
error ("Insufficient memory to %s %s",
"record interface", ifp -> ifr_name);
strcpy (tmp -> name, ifp -> ifr_name);
tmp -> next = interfaces;
tmp -> flags = ir;
interfaces = tmp;
}
/* If we have the capability, extract link information
and record it in a linked list. */
#ifdef AF_LINK
if (ifp -> ifr_addr.sa_family == AF_LINK) {
struct sockaddr_dl *foo = ((struct sockaddr_dl *)
(&ifp -> ifr_addr));
tmp -> hw_address.hlen = foo -> sdl_alen;
tmp -> hw_address.htype = HTYPE_ETHER; /* XXX */
memcpy (tmp -> hw_address.haddr,
LLADDR (foo), foo -> sdl_alen);
} else
#endif /* AF_LINK */
if (ifp -> ifr_addr.sa_family == AF_INET) {
struct iaddr addr;
#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
struct ifreq ifr;
struct sockaddr sa;
int b, sk;
/* Read the hardware address from this interface. */
ifr = *ifp;
if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
error ("Can't get hardware address for %s: %m",
ifr.ifr_name);
sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
switch (sa.sa_family) {
#ifdef ARPHRD_LOOPBACK
case ARPHRD_LOOPBACK:
/* ignore loopback interface */
break;
#endif
case ARPHRD_ETHER:
tmp -> hw_address.hlen = 6;
tmp -> hw_address.htype = ARPHRD_ETHER;
memcpy (tmp -> hw_address.haddr,
sa.sa_data, 6);
break;
#ifndef ARPHRD_IEEE802
# define ARPHRD_IEEE802 HTYPE_IEEE802
#endif
case ARPHRD_IEEE802:
tmp -> hw_address.hlen = 6;
tmp -> hw_address.htype = ARPHRD_IEEE802;
memcpy (tmp -> hw_address.haddr,
sa.sa_data, 6);
break;
#ifdef ARPHRD_METRICOM
case ARPHRD_METRICOM:
tmp -> hw_address.hlen = 6;
tmp -> hw_address.htype = ARPHRD_METRICOM;
memcpy (tmp -> hw_address.haddr,
sa.sa_data, 6);
break;
#endif
default:
error ("%s: unknown hardware address type %d",
ifr.ifr_name, sa.sa_family);
}
#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
/* Get a pointer to the address... */
memcpy (&foo, &ifp -> ifr_addr,
sizeof ifp -> ifr_addr);
/* We don't want the loopback interface. */
if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK))
continue;
/* If this is the first real IP address we've
found, keep a pointer to ifreq structure in
which we found it. */
if (!tmp -> ifp) {
struct ifreq *tif;
#ifdef HAVE_SA_LEN
int len = ((sizeof ifp -> ifr_name) +
ifp -> ifr_addr.sa_len);
#else
int len = sizeof *ifp;
#endif
tif = (struct ifreq *)malloc (len);
if (!tif)
error ("no space to remember ifp.");
memcpy (tif, ifp, len);
tmp -> ifp = tif;
tmp -> primary_address = foo.sin_addr;
}
/* Grab the address... */
addr.len = 4;
memcpy (addr.iabuf, &foo.sin_addr.s_addr,
addr.len);
/* If there's a registered subnet for this address,
connect it together... */
if ((subnet = find_subnet (addr))) {
/* If this interface has multiple aliases
on the same subnet, ignore all but the
first we encounter. */
if (!subnet -> interface) {
subnet -> interface = tmp;
subnet -> interface_address = addr;
} else if (subnet -> interface != tmp) {
warn ("Multiple %s %s: %s %s",
"interfaces match the",
"same subnet",
subnet -> interface -> name,
tmp -> name);
}
share = subnet -> shared_network;
if (tmp -> shared_network &&
tmp -> shared_network != share) {
warn ("Interface %s matches %s",
tmp -> name,
"multiple shared networks");
} else {
tmp -> shared_network = share;
}
if (!share -> interface) {
share -> interface = tmp;
} else if (share -> interface != tmp) {
warn ("Multiple %s %s: %s %s",
"interfaces match the",
"same shared network",
share -> interface -> name,
tmp -> name);
}
}
}
}
/* If we're just trying to get a list of interfaces that we might
be able to configure, we can quit now. */
if (state == DISCOVER_UNCONFIGURED)
return;
/* Weed out the interfaces that did not have IP addresses. */
last = (struct interface_info *)0;
for (tmp = interfaces; tmp; tmp = next) {
next = tmp -> next;
if ((tmp -> flags & INTERFACE_AUTOMATIC) &&
state == DISCOVER_REQUESTED)
tmp -> flags &= ~(INTERFACE_AUTOMATIC |
INTERFACE_REQUESTED);
if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) {
if ((tmp -> flags & INTERFACE_REQUESTED) != ir)
error ("%s: not found", tmp -> name);
if (!last)
interfaces = interfaces -> next;
else
last -> next = tmp -> next;
/* Remember the interface in case we need to know
about it later. */
tmp -> next = dummy_interfaces;
dummy_interfaces = tmp;
continue;
}
last = tmp;
memcpy (&foo, &tmp -> ifp -> ifr_addr,
sizeof tmp -> ifp -> ifr_addr);
/* We must have a subnet declaration for each interface. */
if (!tmp -> shared_network && (state == DISCOVER_SERVER))
error ("No subnet declaration for %s (%s).",
tmp -> name, inet_ntoa (foo.sin_addr));
/* Find subnets that don't have valid interface
addresses... */
for (subnet = (tmp -> shared_network
? tmp -> shared_network -> subnets
: (struct subnet *)0);
subnet; subnet = subnet -> next_sibling) {
if (!subnet -> interface_address.len) {
/* Set the interface address for this subnet
to the first address we found. */
subnet -> interface_address.len = 4;
memcpy (subnet -> interface_address.iabuf,
&foo.sin_addr.s_addr, 4);
}
}
/* Register the interface... */
if_register_receive (tmp);
if_register_send (tmp);
}
/* Now register all the remaining interfaces as protocols. */
for (tmp = interfaces; tmp; tmp = tmp -> next)
add_protocol (tmp -> name, tmp -> rfdesc, got_one, tmp);
close (sock);
#ifdef USE_FALLBACK
strcpy (fallback_interface.name, "fallback");
fallback_interface.shared_network = &fallback_network;
fallback_network.name = "fallback-net";
if_register_fallback (&fallback_interface);
add_protocol ("fallback", fallback_interface.wfdesc,
fallback_discard, &fallback_interface);
#endif
}
void reinitialize_interfaces ()
{
struct interface_info *ip;
for (ip = interfaces; ip; ip = ip -> next) {
if_reinitialize_receive (ip);
if_reinitialize_send (ip);
}
#ifdef USE_FALLBACK
if_reinitialize_fallback (&fallback_interface);
#endif
interfaces_invalidated = 1;
}
#ifdef USE_POLL
/* Wait for packets to come in using poll(). Anyway, when a packet
comes in, call receive_packet to receive the packet and possibly
strip hardware addressing information from it, and then call
do_packet to try to do something with it.
As you can see by comparing this with the code that uses select(),
below, this is gratuitously complex. Quelle surprise, eh? This is
SysV we're talking about, after all, and even in the 90's, it
wouldn't do for SysV to make networking *easy*, would it? Rant,
rant... */
void dispatch ()
{
struct protocol *l;
int nfds = 0;
struct pollfd *fds;
int count;
int i;
int to_msec;
nfds = 0;
for (l = protocols; l; l = l -> next) {
++nfds;
}
fds = (struct pollfd *)malloc ((nfds) * sizeof (struct pollfd));
if (!fds)
error ("Can't allocate poll structures.");
do {
/* Call any expired timeouts, and then if there's
still a timeout registered, time out the select
call then. */
another:
if (timeouts) {
struct timeout *t;
if (timeouts -> when <= cur_time) {
t = timeouts;
timeouts = timeouts -> next;
(*(t -> func)) (t -> what);
t -> next = free_timeouts;
free_timeouts = t;
goto another;
}
/* Figure timeout in milliseconds, and check for
potential overflow. We assume that integers
are 32 bits, which is harmless if they're 64
bits - we'll just get extra timeouts in that
case. Lease times would have to be quite
long in order for a 32-bit integer to overflow,
anyway. */
to_msec = timeouts -> when - cur_time;
if (to_msec > 2147483)
to_msec = 2147483;
to_msec *= 1000;
} else
to_msec = -1;
/* Set up the descriptors to be polled. */
i = 0;
for (l = protocols; l; l = l -> next) {
fds [i].fd = l -> fd;
fds [i].events = POLLIN;
fds [i].revents = 0;
++i;
}
/* Wait for a packet or a timeout... XXX */
count = poll (fds, nfds, to_msec);
/* Get the current time... */
GET_TIME (&cur_time);
/* Not likely to be transitory... */
if (count < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
else
error ("poll: %m");
}
i = 0;
for (l = protocols; l; l = l -> next) {
if ((fds [i].revents & POLLIN)) {
fds [i].revents = 0;
if (l -> handler)
(*(l -> handler)) (l);
if (interfaces_invalidated)
break;
}
++i;
}
interfaces_invalidated = 0;
} while (1);
}
#else
/* Wait for packets to come in using select(). When one does, call
receive_packet to receive the packet and possibly strip hardware
addressing information from it, and then call do_packet to try to
do something with it. */
void dispatch ()
{
fd_set r, w, x;
struct protocol *l;
int max = 0;
int count;
struct timeval tv, *tvp;
FD_ZERO (&w);
FD_ZERO (&x);
do {
/* Call any expired timeouts, and then if there's
still a timeout registered, time out the select
call then. */
another:
if (timeouts) {
struct timeout *t;
if (timeouts -> when <= cur_time) {
t = timeouts;
timeouts = timeouts -> next;
(*(t -> func)) (t -> what);
t -> next = free_timeouts;
free_timeouts = t;
goto another;
}
tv.tv_sec = timeouts -> when - cur_time;
tv.tv_usec = 0;
tvp = &tv;
} else
tvp = (struct timeval *)0;
/* Set up the read mask. */
FD_ZERO (&r);
for (l = protocols; l; l = l -> next) {
FD_SET (l -> fd, &r);
if (l -> fd > max)
max = l -> fd;
}
/* Wait for a packet or a timeout... XXX */
count = select (max + 1, &r, &w, &x, tvp);
/* Get the current time... */
GET_TIME (&cur_time);
/* Not likely to be transitory... */
if (count < 0)
error ("select: %m");
for (l = protocols; l; l = l -> next) {
if (!FD_ISSET (l -> fd, &r))
continue;
if (l -> handler)
(*(l -> handler)) (l);
if (interfaces_invalidated)
break;
}
interfaces_invalidated = 0;
} while (1);
}
#endif /* USE_POLL */
static void got_one (l)
struct protocol *l;
{
struct sockaddr_in from;
struct hardware hfrom;
struct iaddr ifrom;
int result;
union {
unsigned char packbuf [4095]; /* Packet input buffer.
Must be as large as largest
possible MTU. */
struct dhcp_packet packet;
} u;
struct interface_info *ip = l -> local;
if ((result =
receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)) < 0) {
warn ("receive_packet failed on %s: %m", ip -> name);
return;
}
if (result == 0)
return;
if (bootp_packet_handler) {
ifrom.len = 4;
memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
(*bootp_packet_handler) (ip, &u.packet, result,
from.sin_port, ifrom, &hfrom);
}
}
int locate_network (packet)
struct packet *packet;
{
struct iaddr ia;
/* If this came through a gateway, find the corresponding subnet... */
if (packet -> raw -> giaddr.s_addr) {
struct subnet *subnet;
ia.len = 4;
memcpy (ia.iabuf, &packet -> raw -> giaddr, 4);
subnet = find_subnet (ia);
if (subnet)
packet -> shared_network = subnet -> shared_network;
else
packet -> shared_network = (struct shared_network *)0;
} else {
packet -> shared_network =
packet -> interface -> shared_network;
}
if (packet -> shared_network)
return 1;
return 0;
}
void add_timeout (when, where, what)
TIME when;
void (*where) PROTO ((void *));
void *what;
{
struct timeout *t, *q;
/* See if this timeout supersedes an existing timeout. */
t = (struct timeout *)0;
for (q = timeouts; q; q = q -> next) {
if (q -> func == where && q -> what == what) {
if (t)
t -> next = q -> next;
else
timeouts = q -> next;
break;
}
t = q;
}
/* If we didn't supersede a timeout, allocate a timeout
structure now. */
if (!q) {
if (free_timeouts) {
q = free_timeouts;
free_timeouts = q -> next;
q -> func = where;
q -> what = what;
} else {
q = (struct timeout *)malloc (sizeof (struct timeout));
if (!q)
error ("Can't allocate timeout structure!");
q -> func = where;
q -> what = what;
}
}
q -> when = when;
/* Now sort this timeout into the timeout list. */
/* Beginning of list? */
if (!timeouts || timeouts -> when > q -> when) {
q -> next = timeouts;
timeouts = q;
return;
}
/* Middle of list? */
for (t = timeouts; t -> next; t = t -> next) {
if (t -> next -> when > q -> when) {
q -> next = t -> next;
t -> next = q;
return;
}
}
/* End of list. */
t -> next = q;
q -> next = (struct timeout *)0;
}
void cancel_timeout (where, what)
void (*where) PROTO ((void *));
void *what;
{
struct timeout *t, *q;
/* Look for this timeout on the list, and unlink it if we find it. */
t = (struct timeout *)0;
for (q = timeouts; q; q = q -> next) {
if (q -> func == where && q -> what == what) {
if (t)
t -> next = q -> next;
else
timeouts = q -> next;
break;
}
t = q;
}
/* If we found the timeout, put it on the free list. */
if (q) {
q -> next = free_timeouts;
free_timeouts = q;
}
}
/* Add a protocol to the list of protocols... */
void add_protocol (name, fd, handler, local)
char *name;
int fd;
void (*handler) PROTO ((struct protocol *));
void *local;
{
struct protocol *p;
p = (struct protocol *)malloc (sizeof *p);
if (!p)
error ("can't allocate protocol struct for %s", name);
p -> fd = fd;
p -> handler = handler;
p -> local = local;
p -> next = protocols;
protocols = p;
}
void remove_protocol (proto)
struct protocol *proto;
{
struct protocol *p, *next, *prev;
prev = (struct protocol *)0;
for (p = protocols; p; p = next) {
next = p -> next;
if (p == proto) {
if (prev)
prev -> next = p -> next;
else
protocols = p -> next;
free (p);
}
}
}

View File

@ -0,0 +1,391 @@
/* errwarn.c
Errors and warnings... */
/*
* Copyright (c) 1996 The Internet Software Consortium.
* All Rights Reserved.
* Copyright (c) 1995 RadioMail Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RadioMail Corporation, the Internet Software
* Consortium nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY RADIOMAIL CORPORATION, THE INTERNET
* SOFTWARE CONSORTIUM AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL RADIOMAIL CORPORATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software was written for RadioMail Corporation by Ted Lemon
* under a contract with Vixie Enterprises. Further modifications have
* been made for the Internet Software Consortium under a contract
* with Vixie Laboratories.
*/
#ifndef lint
static char copyright[] =
"$Id: errwarn.c,v 1.15 1997/05/09 08:03:44 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <errno.h>
static void do_percentm PROTO ((char *obuf, char *ibuf));
static char mbuf [1024];
static char fbuf [1024];
int warnings_occurred;
/* Log an error message, then exit... */
void error (ANSI_DECL(char *) fmt, VA_DOTDOTDOT)
KandR (char *fmt;)
va_dcl
{
va_list list;
extern int logged_in;
do_percentm (fbuf, fmt);
VA_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
syslog (log_priority | LOG_ERR, mbuf);
#endif
/* Also log it to stderr? */
if (log_perror) {
write (2, mbuf, strlen (mbuf));
write (2, "\n", 1);
}
syslog (LOG_CRIT, "exiting.");
if (log_perror) {
fprintf (stderr, "exiting.\n");
fflush (stderr);
}
cleanup ();
exit (1);
}
/* Log a warning message... */
int warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
KandR (char *fmt;)
va_dcl
{
va_list list;
do_percentm (fbuf, fmt);
VA_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
syslog (log_priority | LOG_ERR, mbuf);
#endif
if (log_perror) {
write (2, mbuf, strlen (mbuf));
write (2, "\n", 1);
}
return 0;
}
/* Log a note... */
int note (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
KandR (char *fmt;)
va_dcl
{
va_list list;
do_percentm (fbuf, fmt);
VA_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
syslog (log_priority | LOG_INFO, mbuf);
#endif
if (log_perror) {
write (2, mbuf, strlen (mbuf));
write (2, "\n", 1);
}
return 0;
}
/* Log a debug message... */
int debug (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
KandR (char *fmt;)
va_dcl
{
va_list list;
do_percentm (fbuf, fmt);
VA_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
syslog (log_priority | LOG_DEBUG, mbuf);
#endif
if (log_perror) {
write (2, mbuf, strlen (mbuf));
write (2, "\n", 1);
}
return 0;
}
/* Find %m in the input string and substitute an error message string. */
static void do_percentm (obuf, ibuf)
char *obuf;
char *ibuf;
{
char *s = ibuf;
char *p = obuf;
int infmt = 0;
char *m;
while (*s)
{
if (infmt)
{
if (*s == 'm')
{
#ifndef __CYGWIN32__
m = strerror (errno);
#else
m = pWSAError ();
#endif
if (!m)
m = "<unknown error>";
strcpy (p - 1, m);
p += strlen (p);
++s;
}
else
*p++ = *s++;
infmt = 0;
}
else
{
if (*s == '%')
infmt = 1;
*p++ = *s++;
}
}
*p = 0;
}
int parse_warn (ANSI_DECL (char *) fmt, VA_DOTDOTDOT)
KandR (char *fmt;)
va_dcl
{
va_list list;
static char spaces [] = " ";
do_percentm (mbuf, fmt);
#ifndef NO_SNPRINTF
snprintf (fbuf, sizeof fbuf, "%s line %d: %s",
tlname, lexline, mbuf);
#else
sprintf (fbuf, "%s line %d: %s",
tlname, lexline, mbuf);
#endif
VA_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
syslog (log_priority | LOG_ERR, mbuf);
syslog (log_priority | LOG_ERR, token_line);
if (lexline < 81)
syslog (log_priority | LOG_ERR,
"%s^", &spaces [sizeof spaces - lexchar]);
#endif
if (log_perror) {
write (2, mbuf, strlen (mbuf));
write (2, "\n", 1);
write (2, token_line, strlen (token_line));
write (2, "\n", 1);
write (2, spaces, lexchar - 1);
write (2, "^\n", 2);
}
warnings_occurred = 1;
return 0;
}
#ifdef NO_STRERROR
char *strerror (err)
int err;
{
extern char *sys_errlist [];
extern int sys_nerr;
static char errbuf [128];
if (err < 0 || err >= sys_nerr) {
sprintf (errbuf, "Error %d", err);
return errbuf;
}
return sys_errlist [err];
}
#endif /* NO_STRERROR */
#ifdef _WIN32
char *pWSAError ()
{
int err = WSAGetLastError ();
switch (err)
{
case WSAEACCES:
return "Permission denied";
case WSAEADDRINUSE:
return "Address already in use";
case WSAEADDRNOTAVAIL:
return "Cannot assign requested address";
case WSAEAFNOSUPPORT:
return "Address family not supported by protocol family";
case WSAEALREADY:
return "Operation already in progress";
case WSAECONNABORTED:
return "Software caused connection abort";
case WSAECONNREFUSED:
return "Connection refused";
case WSAECONNRESET:
return "Connection reset by peer";
case WSAEDESTADDRREQ:
return "Destination address required";
case WSAEFAULT:
return "Bad address";
case WSAEHOSTDOWN:
return "Host is down";
case WSAEHOSTUNREACH:
return "No route to host";
case WSAEINPROGRESS:
return "Operation now in progress";
case WSAEINTR:
return "Interrupted function call";
case WSAEINVAL:
return "Invalid argument";
case WSAEISCONN:
return "Socket is already connected";
case WSAEMFILE:
return "Too many open files";
case WSAEMSGSIZE:
return "Message too long";
case WSAENETDOWN:
return "Network is down";
case WSAENETRESET:
return "Network dropped connection on reset";
case WSAENETUNREACH:
return "Network is unreachable";
case WSAENOBUFS:
return "No buffer space available";
case WSAENOPROTOOPT:
return "Bad protocol option";
case WSAENOTCONN:
return "Socket is not connected";
case WSAENOTSOCK:
return "Socket operation on non-socket";
case WSAEOPNOTSUPP:
return "Operation not supported";
case WSAEPFNOSUPPORT:
return "Protocol family not supported";
case WSAEPROCLIM:
return "Too many processes";
case WSAEPROTONOSUPPORT:
return "Protocol not supported";
case WSAEPROTOTYPE:
return "Protocol wrong type for socket";
case WSAESHUTDOWN:
return "Cannot send after socket shutdown";
case WSAESOCKTNOSUPPORT:
return "Socket type not supported";
case WSAETIMEDOUT:
return "Connection timed out";
case WSAEWOULDBLOCK:
return "Resource temporarily unavailable";
case WSAHOST_NOT_FOUND:
return "Host not found";
#if 0
case WSA_INVALID_HANDLE:
return "Specified event object handle is invalid";
case WSA_INVALID_PARAMETER:
return "One or more parameters are invalid";
case WSAINVALIDPROCTABLE:
return "Invalid procedure table from service provider";
case WSAINVALIDPROVIDER:
return "Invalid service provider version number";
case WSA_IO_PENDING:
return "Overlapped operations will complete later";
case WSA_IO_INCOMPLETE:
return "Overlapped I/O event object not in signaled state";
case WSA_NOT_ENOUGH_MEMORY:
return "Insufficient memory available";
#endif
case WSANOTINITIALISED:
return "Successful WSAStartup not yet performer";
case WSANO_DATA:
return "Valid name, no data record of requested type";
case WSANO_RECOVERY:
return "This is a non-recoverable error";
#if 0
case WSAPROVIDERFAILEDINIT:
return "Unable to initialize a service provider";
case WSASYSCALLFAILURE:
return "System call failure";
#endif
case WSASYSNOTREADY:
return "Network subsystem is unavailable";
case WSATRY_AGAIN:
return "Non-authoritative host not found";
case WSAVERNOTSUPPORTED:
return "WINSOCK.DLL version out of range";
case WSAEDISCON:
return "Graceful shutdown in progress";
#if 0
case WSA_OPERATION_ABORTED:
return "Overlapped operation aborted";
#endif
}
return "Unknown WinSock error";
}
#endif /* _WIN32 */

View File

@ -0,0 +1,175 @@
/* hash.c
Routines for manipulating hash tables... */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: hash.c,v 1.9.2.1 1998/06/25 21:11:29 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static INLINE int do_hash PROTO ((unsigned char *, int, int));
struct hash_table *new_hash ()
{
struct hash_table *rv = new_hash_table (DEFAULT_HASH_SIZE, "new_hash");
if (!rv)
return rv;
memset (&rv -> buckets [0], 0,
DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
return rv;
}
static INLINE int do_hash (name, len, size)
unsigned char *name;
int len;
int size;
{
register int accum = 0;
register unsigned char *s = name;
int i = len;
if (i) {
while (i--) {
/* Add the character in... */
accum += *s++;
/* Add carry back in... */
while (accum > 255) {
accum = (accum & 255) + (accum >> 8);
}
}
} else {
while (*s) {
/* Add the character in... */
accum += *s++;
/* Add carry back in... */
while (accum > 255) {
accum = (accum & 255) + (accum >> 8);
}
}
}
return accum % size;
}
void add_hash (table, name, len, pointer)
struct hash_table *table;
int len;
unsigned char *name;
unsigned char *pointer;
{
int hashno;
struct hash_bucket *bp;
if (!table)
return;
hashno = do_hash (name, len, table -> hash_count);
bp = new_hash_bucket ("add_hash");
if (!bp) {
warn ("Can't add %s to hash table.", name);
return;
}
bp -> name = name;
bp -> value = pointer;
bp -> next = table -> buckets [hashno];
bp -> len = len;
table -> buckets [hashno] = bp;
}
void delete_hash_entry (table, name, len)
struct hash_table *table;
int len;
unsigned char *name;
{
int hashno;
struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
if (!table)
return;
hashno = do_hash (name, len, table -> hash_count);
/* Go through the list looking for an entry that matches;
if we find it, delete it. */
for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
if ((!bp -> len &&
!strcmp ((char *)bp -> name, (char *)name)) ||
(bp -> len == len &&
!memcmp (bp -> name, name, len))) {
if (pbp) {
pbp -> next = bp -> next;
} else {
table -> buckets [hashno] = bp -> next;
}
free_hash_bucket (bp, "delete_hash_entry");
break;
}
pbp = bp; /* jwg, 9/6/96 - nice catch! */
}
}
unsigned char *hash_lookup (table, name, len)
struct hash_table *table;
unsigned char *name;
int len;
{
int hashno;
struct hash_bucket *bp;
if (!table)
return (unsigned char *)0;
hashno = do_hash (name, len, table -> hash_count);
if (len) {
for (bp = table -> buckets [hashno]; bp; bp = bp -> next) {
if (len == bp -> len
&& !memcmp (bp -> name, name, len))
return bp -> value;
}
} else {
for (bp = table -> buckets [hashno]; bp; bp = bp -> next)
if (!strcmp ((char *)bp -> name, (char *)name))
return bp -> value;
}
return (unsigned char *)0;
}

View File

@ -0,0 +1,177 @@
/* icmp.c
ICMP Protocol engine - for sending out pings and receiving
responses. */
/*
* Copyright (c) 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: icmp.c,v 1.7.2.1 1998/06/25 21:11:29 mellon Exp $ Copyright (c) 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "netinet/ip.h"
#include "netinet/ip_icmp.h"
static int icmp_protocol_initialized;
static int icmp_protocol_fd;
/* Initialize the ICMP protocol. */
void icmp_startup (routep, handler)
int routep;
void (*handler) PROTO ((struct iaddr, u_int8_t *, int));
{
struct protoent *proto;
int protocol = 1;
struct sockaddr_in from;
int fd;
int state;
/* Only initialize icmp once. */
if (icmp_protocol_initialized)
error ("attempted to reinitialize icmp protocol");
icmp_protocol_initialized = 1;
/* Get the protocol number (should be 1). */
proto = getprotobyname ("icmp");
if (proto)
protocol = proto -> p_proto;
/* Get a raw socket for the ICMP protocol. */
icmp_protocol_fd = socket (AF_INET, SOCK_RAW, protocol);
if (icmp_protocol_fd < 0)
error ("unable to create icmp socket: %m");
/* Make sure it does routing... */
state = 0;
if (setsockopt (icmp_protocol_fd, SOL_SOCKET, SO_DONTROUTE,
(char *)&state, sizeof state) < 0)
error ("Unable to disable SO_DONTROUTE on ICMP socket: %m");
add_protocol ("icmp", icmp_protocol_fd, icmp_echoreply,
(void *)handler);
}
int icmp_echorequest (addr)
struct iaddr *addr;
{
struct sockaddr_in to;
struct icmp icmp;
int status;
if (!icmp_protocol_initialized)
error ("attempt to use ICMP protocol before initialization.");
#ifdef HAVE_SA_LEN
to.sin_len = sizeof to;
#endif
to.sin_family = AF_INET;
to.sin_port = 0; /* unused. */
memcpy (&to.sin_addr, addr -> iabuf, sizeof to.sin_addr); /* XXX */
icmp.icmp_type = ICMP_ECHO;
icmp.icmp_code = 0;
icmp.icmp_cksum = 0;
icmp.icmp_seq = 0;
#ifdef PTRSIZE_64BIT
icmp.icmp_id = (((u_int32_t)(u_int64_t)addr) ^
(u_int32_t)(((u_int64_t)addr) >> 32));
#else
icmp.icmp_id = (u_int32_t)addr;
#endif
icmp.icmp_cksum = wrapsum (checksum ((unsigned char *)&icmp,
sizeof icmp, 0));
/* Send the ICMP packet... */
status = sendto (icmp_protocol_fd, (char *)&icmp, sizeof icmp, 0,
(struct sockaddr *)&to, sizeof to);
if (status < 0)
warn ("icmp_echorequest %s: %m", inet_ntoa(to.sin_addr));
if (status != sizeof icmp)
return 0;
return 1;
}
void icmp_echoreply (protocol)
struct protocol *protocol;
{
struct icmp *icfrom;
struct sockaddr_in from;
u_int8_t icbuf [1500];
int status;
int len;
struct iaddr ia;
void (*handler) PROTO ((struct iaddr, u_int8_t *, int));
len = sizeof from;
status = recvfrom (protocol -> fd, (char *)icbuf, sizeof icbuf, 0,
(struct sockaddr *)&from, &len);
if (status < 0) {
warn ("icmp_echoreply: %m");
return;
}
/* Probably not for us. */
if (status < (sizeof (struct ip)) + (sizeof *icfrom)) {
return;
}
len = status - sizeof (struct ip);
icfrom = (struct icmp *)(icbuf + sizeof (struct ip));
/* Silently discard ICMP packets that aren't echoreplies. */
if (icfrom -> icmp_type != ICMP_ECHOREPLY) {
return;
}
/* If we were given a second-stage handler, call it. */
if (protocol -> local) {
handler = ((void (*) PROTO ((struct iaddr,
u_int8_t *, int)))
protocol -> local);
memcpy (ia.iabuf, &from.sin_addr, sizeof from.sin_addr);
ia.len = sizeof from.sin_addr;
(*handler) (ia, icbuf, len);
}
}

View File

@ -0,0 +1,178 @@
/* inet.c
Subroutines to manipulate internet addresses in a safely portable
way... */
/*
* Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#include "dhcpd.h"
/* Return just the network number of an internet address... */
struct iaddr subnet_number (addr, mask)
struct iaddr addr;
struct iaddr mask;
{
int i;
struct iaddr rv;
rv.len = 0;
/* Both addresses must have the same length... */
if (addr.len != mask.len)
return rv;
rv.len = addr.len;
for (i = 0; i < rv.len; i++)
rv.iabuf [i] = addr.iabuf [i] & mask.iabuf [i];
return rv;
}
/* Combine a network number and a integer to produce an internet address.
This won't work for subnets with more than 32 bits of host address, but
maybe this isn't a problem. */
struct iaddr ip_addr (subnet, mask, host_address)
struct iaddr subnet;
struct iaddr mask;
u_int32_t host_address;
{
int i, j, k;
u_int32_t swaddr;
struct iaddr rv;
unsigned char habuf [sizeof swaddr];
swaddr = htonl (host_address);
memcpy (habuf, &swaddr, sizeof swaddr);
/* Combine the subnet address and the host address. If
the host address is bigger than can fit in the subnet,
return a zero-length iaddr structure. */
rv = subnet;
j = rv.len - sizeof habuf;
for (i = sizeof habuf - 1; i >= 0; i--) {
if (mask.iabuf [i + j]) {
if (habuf [i] > (mask.iabuf [i + j] ^ 0xFF)) {
rv.len = 0;
return rv;
}
for (k = i - 1; k >= 0; k--) {
if (habuf [k]) {
rv.len = 0;
return rv;
}
}
rv.iabuf [i + j] |= habuf [i];
break;
} else
rv.iabuf [i + j] = habuf [i];
}
return rv;
}
/* Given a subnet number and netmask, return the address on that subnet
for which the host portion of the address is all ones (the standard
broadcast address). */
struct iaddr broadcast_addr (subnet, mask)
struct iaddr subnet;
struct iaddr mask;
{
int i, j, k;
struct iaddr rv;
if (subnet.len != mask.len) {
rv.len = 0;
return rv;
}
for (i = 0; i < subnet.len; i++) {
rv.iabuf [i] = subnet.iabuf [i] | (~mask.iabuf [i] & 255);
}
rv.len = subnet.len;
return rv;
}
u_int32_t host_addr (addr, mask)
struct iaddr addr;
struct iaddr mask;
{
int i;
u_int32_t swaddr;
struct iaddr rv;
rv.len = 0;
/* Mask out the network bits... */
rv.len = addr.len;
for (i = 0; i < rv.len; i++)
rv.iabuf [i] = addr.iabuf [i] & ~mask.iabuf [i];
/* Copy out up to 32 bits... */
memcpy (&swaddr, &rv.iabuf [rv.len - sizeof swaddr], sizeof swaddr);
/* Swap it and return it. */
return ntohl (swaddr);
}
int addr_eq (addr1, addr2)
struct iaddr addr1, addr2;
{
if (addr1.len != addr2.len)
return 0;
return memcmp (addr1.iabuf, addr2.iabuf, addr1.len) == 0;
}
char *piaddr (addr)
struct iaddr addr;
{
static char pbuf [4 * 16];
char *s = pbuf;
int i;
if (addr.len == 0) {
strcpy (s, "<null address>");
}
for (i = 0; i < addr.len; i++) {
sprintf (s, "%s%d", i ? "." : "", addr.iabuf [i]);
s += strlen (s);
}
return pbuf;
}

View File

@ -0,0 +1,150 @@
/* $NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $ */
/*
* Copyright (c) 1983, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
#else
static char rcsid[] = "$NetBSD: inet_addr.c,v 1.6 1996/02/02 15:22:23 mrg Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
#ifndef lint
static char copyright[] =
"$Id: inet_addr.c,v 1.2.2.1 1998/06/26 20:51:35 mellon Exp $ Copyright (c) 1983, 1990, 1993 The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#ifdef NEED_INET_ATON
/*
* Check whether "cp" is a valid ascii representation
* of an Internet address and convert to a binary address.
* Returns 1 if the address is valid, 0 if not.
* This replaces inet_addr, the return value from which
* cannot distinguish between failure and a local broadcast address.
*/
int
inet_aton(cp, addr)
const char *cp;
struct in_addr *addr;
{
register u_long val;
register int base, n;
register char c;
u_int parts[4];
register u_int *pp = parts;
for (;;) {
/*
* Collect number up to ``.''.
* Values are specified as for C:
* 0x=hex, 0=octal, other=decimal.
*/
val = 0; base = 10;
if (*cp == '0') {
if (*++cp == 'x' || *cp == 'X')
base = 16, cp++;
else
base = 8;
}
while ((c = *cp) != '\0') {
if (isascii(c) && isdigit(c)) {
val = (val * base) + (c - '0');
cp++;
continue;
}
if (base == 16 && isascii(c) && isxdigit(c)) {
val = (val << 4) +
(c + 10 - (islower(c) ? 'a' : 'A'));
cp++;
continue;
}
break;
}
if (*cp == '.') {
/*
* Internet format:
* a.b.c.d
* a.b.c (with c treated as 16-bits)
* a.b (with b treated as 24 bits)
*/
if (pp >= parts + 3 || val > 0xff)
return (0);
*pp++ = val, cp++;
} else
break;
}
/*
* Check for trailing characters.
*/
if (*cp && (!isascii(*cp) || !isspace(*cp)))
return (0);
/*
* Concoct the address according to
* the number of parts specified.
*/
n = pp - parts + 1;
switch (n) {
case 0:
return (0); /* initial nondigit */
case 1: /* a -- 32 bits */
break;
case 2: /* a.b -- 8.24 bits */
if (val > 0xffffff)
return (0);
val |= parts[0] << 24;
break;
case 3: /* a.b.c -- 8.8.16 bits */
if (val > 0xffff)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16);
break;
case 4: /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xff)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
break;
}
if (addr)
addr->s_addr = htonl(val);
return (1);
}
#endif

View File

@ -0,0 +1,911 @@
/* memory.c
Memory-resident database... */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: memory.c,v 1.35.2.2 1998/06/25 21:11:30 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static struct subnet *subnets;
static struct shared_network *shared_networks;
static struct hash_table *host_hw_addr_hash;
static struct hash_table *host_uid_hash;
static struct hash_table *lease_uid_hash;
static struct hash_table *lease_ip_addr_hash;
static struct hash_table *lease_hw_addr_hash;
static struct lease *dangling_leases;
static struct hash_table *vendor_class_hash;
static struct hash_table *user_class_hash;
void enter_host (hd)
struct host_decl *hd;
{
struct host_decl *hp = (struct host_decl *)0;
struct host_decl *np = (struct host_decl *)0;
hd -> n_ipaddr = (struct host_decl *)0;
if (hd -> interface.hlen) {
if (!host_hw_addr_hash)
host_hw_addr_hash = new_hash ();
else
hp = (struct host_decl *)
hash_lookup (host_hw_addr_hash,
hd -> interface.haddr,
hd -> interface.hlen);
/* If there isn't already a host decl matching this
address, add it to the hash table. */
if (!hp)
add_hash (host_hw_addr_hash,
hd -> interface.haddr, hd -> interface.hlen,
(unsigned char *)hd);
}
/* If there was already a host declaration for this hardware
address, add this one to the end of the list. */
if (hp) {
for (np = hp; np -> n_ipaddr; np = np -> n_ipaddr)
;
np -> n_ipaddr = hd;
}
if (hd -> group -> options [DHO_DHCP_CLIENT_IDENTIFIER]) {
if (!tree_evaluate (hd -> group -> options
[DHO_DHCP_CLIENT_IDENTIFIER]))
return;
/* If there's no uid hash, make one; otherwise, see if
there's already an entry in the hash for this host. */
if (!host_uid_hash) {
host_uid_hash = new_hash ();
hp = (struct host_decl *)0;
} else
hp = (struct host_decl *) hash_lookup
(host_uid_hash,
hd -> group -> options
[DHO_DHCP_CLIENT_IDENTIFIER] -> value,
hd -> group -> options
[DHO_DHCP_CLIENT_IDENTIFIER] -> len);
/* If there's already a host declaration for this
client identifier, add this one to the end of the
list. Otherwise, add it to the hash table. */
if (hp) {
/* Don't link it in twice... */
if (!np) {
for (np = hp; np -> n_ipaddr;
np = np -> n_ipaddr)
;
np -> n_ipaddr = hd;
}
} else {
add_hash (host_uid_hash,
hd -> group -> options
[DHO_DHCP_CLIENT_IDENTIFIER] -> value,
hd -> group -> options
[DHO_DHCP_CLIENT_IDENTIFIER] -> len,
(unsigned char *)hd);
}
}
}
struct host_decl *find_hosts_by_haddr (htype, haddr, hlen)
int htype;
unsigned char *haddr;
int hlen;
{
struct host_decl *foo;
foo = (struct host_decl *)hash_lookup (host_hw_addr_hash,
haddr, hlen);
return foo;
}
struct host_decl *find_hosts_by_uid (data, len)
unsigned char *data;
int len;
{
struct host_decl *foo;
foo = (struct host_decl *)hash_lookup (host_uid_hash, data, len);
return foo;
}
/* More than one host_decl can be returned by find_hosts_by_haddr or
find_hosts_by_uid, and each host_decl can have multiple addresses.
Loop through the list of hosts, and then for each host, through the
list of addresses, looking for an address that's in the same shared
network as the one specified. Store the matching address through
the addr pointer, update the host pointer to point at the host_decl
that matched, and return the subnet that matched. */
struct subnet *find_host_for_network (host, addr, share)
struct host_decl **host;
struct iaddr *addr;
struct shared_network *share;
{
int i;
struct subnet *subnet;
struct iaddr ip_address;
struct host_decl *hp;
for (hp = *host; hp; hp = hp -> n_ipaddr) {
if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr))
continue;
for (i = 0; i < hp -> fixed_addr -> len; i += 4) {
ip_address.len = 4;
memcpy (ip_address.iabuf,
hp -> fixed_addr -> value + i, 4);
subnet = find_grouped_subnet (share, ip_address);
if (subnet) {
*addr = ip_address;
*host = hp;
return subnet;
}
}
}
return (struct subnet *)0;
}
void new_address_range (low, high, subnet, dynamic)
struct iaddr low, high;
struct subnet *subnet;
int dynamic;
{
struct lease *address_range, *lp, *plp;
struct iaddr net;
int min, max, i;
char lowbuf [16], highbuf [16], netbuf [16];
struct shared_network *share = subnet -> shared_network;
struct hostent *h;
struct in_addr ia;
/* All subnets should have attached shared network structures. */
if (!share) {
strcpy (netbuf, piaddr (subnet -> net));
error ("No shared network for network %s (%s)",
netbuf, piaddr (subnet -> netmask));
}
/* Initialize the hash table if it hasn't been done yet. */
if (!lease_uid_hash)
lease_uid_hash = new_hash ();
if (!lease_ip_addr_hash)
lease_ip_addr_hash = new_hash ();
if (!lease_hw_addr_hash)
lease_hw_addr_hash = new_hash ();
/* Make sure that high and low addresses are in same subnet. */
net = subnet_number (low, subnet -> netmask);
if (!addr_eq (net, subnet_number (high, subnet -> netmask))) {
strcpy (lowbuf, piaddr (low));
strcpy (highbuf, piaddr (high));
strcpy (netbuf, piaddr (subnet -> netmask));
error ("Address range %s to %s, netmask %s spans %s!",
lowbuf, highbuf, netbuf, "multiple subnets");
}
/* Make sure that the addresses are on the correct subnet. */
if (!addr_eq (net, subnet -> net)) {
strcpy (lowbuf, piaddr (low));
strcpy (highbuf, piaddr (high));
strcpy (netbuf, piaddr (subnet -> netmask));
error ("Address range %s to %s not on net %s/%s!",
lowbuf, highbuf, piaddr (subnet -> net), netbuf);
}
/* Get the high and low host addresses... */
max = host_addr (high, subnet -> netmask);
min = host_addr (low, subnet -> netmask);
/* Allow range to be specified high-to-low as well as low-to-high. */
if (min > max) {
max = min;
min = host_addr (high, subnet -> netmask);
}
/* Get a lease structure for each address in the range. */
address_range = new_leases (max - min + 1, "new_address_range");
if (!address_range) {
strcpy (lowbuf, piaddr (low));
strcpy (highbuf, piaddr (high));
error ("No memory for address range %s-%s.", lowbuf, highbuf);
}
memset (address_range, 0, (sizeof *address_range) * (max - min + 1));
/* Fill in the last lease if it hasn't been already... */
if (!share -> last_lease) {
share -> last_lease = &address_range [0];
}
/* Fill out the lease structures with some minimal information. */
for (i = 0; i < max - min + 1; i++) {
address_range [i].ip_addr =
ip_addr (subnet -> net, subnet -> netmask, i + min);
address_range [i].starts =
address_range [i].timestamp = MIN_TIME;
address_range [i].ends = MIN_TIME;
address_range [i].subnet = subnet;
address_range [i].shared_network = share;
address_range [i].flags = dynamic ? DYNAMIC_BOOTP_OK : 0;
memcpy (&ia, address_range [i].ip_addr.iabuf, 4);
if (subnet -> group -> get_lease_hostnames) {
h = gethostbyaddr ((char *)&ia, sizeof ia, AF_INET);
if (!h)
warn ("No hostname for %s", inet_ntoa (ia));
else {
address_range [i].hostname =
malloc (strlen (h -> h_name) + 1);
if (!address_range [i].hostname)
error ("no memory for hostname %s.",
h -> h_name);
strcpy (address_range [i].hostname,
h -> h_name);
}
}
/* Link this entry into the list. */
address_range [i].next = share -> leases;
address_range [i].prev = (struct lease *)0;
share -> leases = &address_range [i];
if (address_range [i].next)
address_range [i].next -> prev = share -> leases;
add_hash (lease_ip_addr_hash,
address_range [i].ip_addr.iabuf,
address_range [i].ip_addr.len,
(unsigned char *)&address_range [i]);
}
/* Find out if any dangling leases are in range... */
plp = (struct lease *)0;
for (lp = dangling_leases; lp; lp = lp -> next) {
struct iaddr lnet;
int lhost;
lnet = subnet_number (lp -> ip_addr, subnet -> netmask);
lhost = host_addr (lp -> ip_addr, subnet -> netmask);
/* If it's in range, fill in the real lease structure with
the dangling lease's values, and remove the lease from
the list of dangling leases. */
if (addr_eq (lnet, subnet -> net) &&
lhost >= i && lhost <= max) {
if (plp) {
plp -> next = lp -> next;
} else {
dangling_leases = lp -> next;
}
lp -> next = (struct lease *)0;
address_range [lhost - i].hostname = lp -> hostname;
address_range [lhost - i].client_hostname =
lp -> client_hostname;
supersede_lease (&address_range [lhost - i], lp, 0);
free_lease (lp, "new_address_range");
} else
plp = lp;
}
}
struct subnet *find_subnet (addr)
struct iaddr addr;
{
struct subnet *rv;
for (rv = subnets; rv; rv = rv -> next_subnet) {
if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
return rv;
}
return (struct subnet *)0;
}
struct subnet *find_grouped_subnet (share, addr)
struct shared_network *share;
struct iaddr addr;
{
struct subnet *rv;
for (rv = share -> subnets; rv; rv = rv -> next_sibling) {
if (addr_eq (subnet_number (addr, rv -> netmask), rv -> net))
return rv;
}
return (struct subnet *)0;
}
/* Enter a new subnet into the subnet list. */
void enter_subnet (subnet)
struct subnet *subnet;
{
struct subnet *scan;
/* Check for duplicates... */
for (scan = subnets; scan; scan = scan -> next_subnet) {
if (addr_eq (subnet_number (subnet -> net, scan -> netmask),
scan -> net) ||
addr_eq (subnet_number (scan -> net, subnet -> netmask),
subnet -> net)) {
char n1buf [16];
int i, j;
for (i = 0; i < 32; i++)
if (subnet -> netmask.iabuf [3 - (i >> 3)]
& (1 << (i & 7)))
break;
for (j = 0; j < 32; j++)
if (scan -> netmask.iabuf [3 - (j >> 3)]
& (1 << (j & 7)))
break;
strcpy (n1buf, piaddr (subnet -> net));
error ("subnet %s/%d conflicts with subnet %s/%d",
n1buf, i, piaddr (scan -> net), j);
}
}
/* XXX Sort the nets into a balanced tree to make searching quicker. */
subnet -> next_subnet = subnets;
subnets = subnet;
}
/* Enter a new shared network into the shared network list. */
void enter_shared_network (share)
struct shared_network *share;
{
/* XXX Sort the nets into a balanced tree to make searching quicker. */
share -> next = shared_networks;
shared_networks = share;
}
/* Enter a lease into the system. This is called by the parser each
time it reads in a new lease. If the subnet for that lease has
already been read in (usually the case), just update that lease;
otherwise, allocate temporary storage for the lease and keep it around
until we're done reading in the config file. */
void enter_lease (lease)
struct lease *lease;
{
struct lease *comp = find_lease_by_ip_addr (lease -> ip_addr);
/* If we don't have a place for this lease yet, save it for
later. */
if (!comp) {
comp = new_lease ("enter_lease");
if (!comp) {
error ("No memory for lease %s\n",
piaddr (lease -> ip_addr));
}
*comp = *lease;
comp -> next = dangling_leases;
comp -> prev = (struct lease *)0;
dangling_leases = comp;
} else {
/* Record the hostname information in the lease. */
comp -> hostname = lease -> hostname;
comp -> client_hostname = lease -> client_hostname;
supersede_lease (comp, lease, 0);
}
}
/* Replace the data in an existing lease with the data in a new lease;
adjust hash tables to suit, and insertion sort the lease into the
list of leases by expiry time so that we can always find the oldest
lease. */
int supersede_lease (comp, lease, commit)
struct lease *comp, *lease;
int commit;
{
int enter_uid = 0;
int enter_hwaddr = 0;
struct lease *lp;
/* Static leases are not currently kept in the database... */
if (lease -> flags & STATIC_LEASE)
return 1;
/* If the existing lease hasn't expired and has a different
unique identifier or, if it doesn't have a unique
identifier, a different hardware address, then the two
leases are in conflict. If the existing lease has a uid
and the new one doesn't, but they both have the same
hardware address, and dynamic bootp is allowed on this
lease, then we allow that, in case a dynamic BOOTP lease is
requested *after* a DHCP lease has been assigned. */
if (!(lease -> flags & ABANDONED_LEASE) &&
comp -> ends > cur_time &&
(((comp -> uid && lease -> uid) &&
(comp -> uid_len != lease -> uid_len ||
memcmp (comp -> uid, lease -> uid, comp -> uid_len))) ||
(!comp -> uid &&
((comp -> hardware_addr.htype !=
lease -> hardware_addr.htype) ||
(comp -> hardware_addr.hlen !=
lease -> hardware_addr.hlen) ||
memcmp (comp -> hardware_addr.haddr,
lease -> hardware_addr.haddr,
comp -> hardware_addr.hlen))))) {
warn ("Lease conflict at %s",
piaddr (comp -> ip_addr));
return 0;
} else {
/* If there's a Unique ID, dissociate it from the hash
table and free it if necessary. */
if (comp -> uid) {
uid_hash_delete (comp);
enter_uid = 1;
if (comp -> uid != &comp -> uid_buf [0]) {
free (comp -> uid);
comp -> uid_max = 0;
comp -> uid_len = 0;
}
comp -> uid = (unsigned char *)0;
} else
enter_uid = 1;
if (comp -> hardware_addr.htype &&
((comp -> hardware_addr.hlen !=
lease -> hardware_addr.hlen) ||
(comp -> hardware_addr.htype !=
lease -> hardware_addr.htype) ||
memcmp (comp -> hardware_addr.haddr,
lease -> hardware_addr.haddr,
comp -> hardware_addr.hlen))) {
hw_hash_delete (comp);
enter_hwaddr = 1;
} else if (!comp -> hardware_addr.htype)
enter_hwaddr = 1;
/* Copy the data files, but not the linkages. */
comp -> starts = lease -> starts;
comp -> timestamp = lease -> timestamp;
if (lease -> uid) {
if (lease -> uid_len < sizeof (lease -> uid_buf)) {
memcpy (comp -> uid_buf,
lease -> uid, lease -> uid_len);
comp -> uid = &comp -> uid_buf [0];
comp -> uid_max = sizeof comp -> uid_buf;
} else if (lease -> uid != &lease -> uid_buf [0]) {
comp -> uid = lease -> uid;
comp -> uid_max = lease -> uid_max;
lease -> uid = (unsigned char *)0;
lease -> uid_max = 0;
} else {
error ("corrupt lease uid."); /* XXX */
}
} else {
comp -> uid = (unsigned char *)0;
comp -> uid_max = 0;
}
comp -> uid_len = lease -> uid_len;
comp -> host = lease -> host;
comp -> hardware_addr = lease -> hardware_addr;
comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) |
(comp -> flags & ~EPHEMERAL_FLAGS));
/* Record the lease in the uid hash if necessary. */
if (enter_uid && lease -> uid) {
uid_hash_add (comp);
}
/* Record it in the hardware address hash if necessary. */
if (enter_hwaddr && lease -> hardware_addr.htype) {
hw_hash_add (comp);
}
/* Remove the lease from its current place in the
timeout sequence. */
if (comp -> prev) {
comp -> prev -> next = comp -> next;
} else {
comp -> shared_network -> leases = comp -> next;
}
if (comp -> next) {
comp -> next -> prev = comp -> prev;
}
if (comp -> shared_network -> last_lease == comp) {
comp -> shared_network -> last_lease = comp -> prev;
}
/* Find the last insertion point... */
if (comp == comp -> shared_network -> insertion_point ||
!comp -> shared_network -> insertion_point) {
lp = comp -> shared_network -> leases;
} else {
lp = comp -> shared_network -> insertion_point;
}
if (!lp) {
/* Nothing on the list yet? Just make comp the
head of the list. */
comp -> shared_network -> leases = comp;
comp -> shared_network -> last_lease = comp;
} else if (lp -> ends > lease -> ends) {
/* Skip down the list until we run out of list
or find a place for comp. */
while (lp -> next && lp -> ends > lease -> ends) {
lp = lp -> next;
}
if (lp -> ends > lease -> ends) {
/* If we ran out of list, put comp
at the end. */
lp -> next = comp;
comp -> prev = lp;
comp -> next = (struct lease *)0;
comp -> shared_network -> last_lease = comp;
} else {
/* If we didn't, put it between lp and
the previous item on the list. */
if ((comp -> prev = lp -> prev))
comp -> prev -> next = comp;
comp -> next = lp;
lp -> prev = comp;
}
} else {
/* Skip up the list until we run out of list
or find a place for comp. */
while (lp -> prev && lp -> ends < lease -> ends) {
lp = lp -> prev;
}
if (lp -> ends < lease -> ends) {
/* If we ran out of list, put comp
at the beginning. */
lp -> prev = comp;
comp -> next = lp;
comp -> prev = (struct lease *)0;
comp -> shared_network -> leases = comp;
} else {
/* If we didn't, put it between lp and
the next item on the list. */
if ((comp -> next = lp -> next))
comp -> next -> prev = comp;
comp -> prev = lp;
lp -> next = comp;
}
}
comp -> shared_network -> insertion_point = comp;
comp -> ends = lease -> ends;
}
/* Return zero if we didn't commit the lease to permanent storage;
nonzero if we did. */
return commit && write_lease (comp) && commit_leases ();
}
/* Release the specified lease and re-hash it as appropriate. */
void release_lease (lease)
struct lease *lease;
{
struct lease lt;
lt = *lease;
lt.ends = cur_time;
supersede_lease (lease, &lt, 1);
}
/* Abandon the specified lease (set its timeout to infinity and its
particulars to zero, and re-hash it as appropriate. */
void abandon_lease (lease, message)
struct lease *lease;
char *message;
{
struct lease lt;
lease -> flags |= ABANDONED_LEASE;
lt = *lease;
lt.ends = cur_time;
warn ("Abandoning IP address %s: %s",
piaddr (lease -> ip_addr), message);
lt.hardware_addr.htype = 0;
lt.hardware_addr.hlen = 0;
lt.uid = (unsigned char *)0;
lt.uid_len = 0;
supersede_lease (lease, &lt, 1);
}
/* Locate the lease associated with a given IP address... */
struct lease *find_lease_by_ip_addr (addr)
struct iaddr addr;
{
struct lease *lease = (struct lease *)hash_lookup (lease_ip_addr_hash,
addr.iabuf,
addr.len);
return lease;
}
struct lease *find_lease_by_uid (uid, len)
unsigned char *uid;
int len;
{
struct lease *lease = (struct lease *)hash_lookup (lease_uid_hash,
uid, len);
return lease;
}
struct lease *find_lease_by_hw_addr (hwaddr, hwlen)
unsigned char *hwaddr;
int hwlen;
{
struct lease *lease = (struct lease *)hash_lookup (lease_hw_addr_hash,
hwaddr, hwlen);
return lease;
}
/* Add the specified lease to the uid hash. */
void uid_hash_add (lease)
struct lease *lease;
{
struct lease *head =
find_lease_by_uid (lease -> uid, lease -> uid_len);
struct lease *scan;
#ifdef DEBUG
if (lease -> n_uid)
abort ();
#endif
/* If it's not in the hash, just add it. */
if (!head)
add_hash (lease_uid_hash, lease -> uid,
lease -> uid_len, (unsigned char *)lease);
else {
/* Otherwise, attach it to the end of the list. */
for (scan = head; scan -> n_uid; scan = scan -> n_uid)
#ifdef DEBUG
if (scan == lease)
abort ()
#endif
;
scan -> n_uid = lease;
}
}
/* Delete the specified lease from the uid hash. */
void uid_hash_delete (lease)
struct lease *lease;
{
struct lease *head =
find_lease_by_uid (lease -> uid, lease -> uid_len);
struct lease *scan;
/* If it's not in the hash, we have no work to do. */
if (!head) {
lease -> n_uid = (struct lease *)0;
return;
}
/* If the lease we're freeing is at the head of the list,
remove the hash table entry and add a new one with the
next lease on the list (if there is one). */
if (head == lease) {
delete_hash_entry (lease_uid_hash,
lease -> uid, lease -> uid_len);
if (lease -> n_uid)
add_hash (lease_uid_hash,
lease -> n_uid -> uid,
lease -> n_uid -> uid_len,
(unsigned char *)(lease -> n_uid));
} else {
/* Otherwise, look for the lease in the list of leases
attached to the hash table entry, and remove it if
we find it. */
for (scan = head; scan -> n_uid; scan = scan -> n_uid) {
if (scan -> n_uid == lease) {
scan -> n_uid = scan -> n_uid -> n_uid;
break;
}
}
}
lease -> n_uid = (struct lease *)0;
}
/* Add the specified lease to the hardware address hash. */
void hw_hash_add (lease)
struct lease *lease;
{
struct lease *head =
find_lease_by_hw_addr (lease -> hardware_addr.haddr,
lease -> hardware_addr.hlen);
struct lease *scan;
/* If it's not in the hash, just add it. */
if (!head)
add_hash (lease_hw_addr_hash,
lease -> hardware_addr.haddr,
lease -> hardware_addr.hlen,
(unsigned char *)lease);
else {
/* Otherwise, attach it to the end of the list. */
for (scan = head; scan -> n_hw; scan = scan -> n_hw)
;
scan -> n_hw = lease;
}
}
/* Delete the specified lease from the hardware address hash. */
void hw_hash_delete (lease)
struct lease *lease;
{
struct lease *head =
find_lease_by_hw_addr (lease -> hardware_addr.haddr,
lease -> hardware_addr.hlen);
struct lease *scan;
/* If it's not in the hash, we have no work to do. */
if (!head) {
lease -> n_hw = (struct lease *)0;
return;
}
/* If the lease we're freeing is at the head of the list,
remove the hash table entry and add a new one with the
next lease on the list (if there is one). */
if (head == lease) {
delete_hash_entry (lease_hw_addr_hash,
lease -> hardware_addr.haddr,
lease -> hardware_addr.hlen);
if (lease -> n_hw)
add_hash (lease_hw_addr_hash,
lease -> n_hw -> hardware_addr.haddr,
lease -> n_hw -> hardware_addr.hlen,
(unsigned char *)(lease -> n_hw));
} else {
/* Otherwise, look for the lease in the list of leases
attached to the hash table entry, and remove it if
we find it. */
for (scan = head; scan -> n_hw; scan = scan -> n_hw) {
if (scan -> n_hw == lease) {
scan -> n_hw = scan -> n_hw -> n_hw;
break;
}
}
}
lease -> n_hw = (struct lease *)0;
}
struct class *add_class (type, name)
int type;
char *name;
{
struct class *class = new_class ("add_class");
char *tname = (char *)malloc (strlen (name) + 1);
if (!vendor_class_hash)
vendor_class_hash = new_hash ();
if (!user_class_hash)
user_class_hash = new_hash ();
if (!tname || !class || !vendor_class_hash || !user_class_hash)
return (struct class *)0;
memset (class, 0, sizeof *class);
strcpy (tname, name);
class -> name = tname;
if (type)
add_hash (user_class_hash,
(unsigned char *)tname, strlen (tname),
(unsigned char *)class);
else
add_hash (vendor_class_hash,
(unsigned char *)tname, strlen (tname),
(unsigned char *)class);
return class;
}
struct class *find_class (type, name, len)
int type;
unsigned char *name;
int len;
{
struct class *class =
(struct class *)hash_lookup (type
? user_class_hash
: vendor_class_hash, name, len);
return class;
}
struct group *clone_group (group, caller)
struct group *group;
char *caller;
{
struct group *g = new_group (caller);
if (!g)
error ("%s: can't allocate new group", caller);
*g = *group;
return g;
}
/* Write all interesting leases to permanent storage. */
void write_leases ()
{
struct lease *l;
struct shared_network *s;
for (s = shared_networks; s; s = s -> next) {
for (l = s -> leases; l; l = l -> next) {
if (l -> hardware_addr.hlen ||
l -> uid_len ||
(l -> flags & ABANDONED_LEASE))
if (!write_lease (l))
error ("Can't rewrite lease database");
}
}
if (!commit_leases ())
error ("Can't commit leases to new database: %m");
}
void dump_subnets ()
{
struct lease *l;
struct shared_network *s;
struct subnet *n;
for (s = shared_networks; s; s = s -> next) {
for (n = subnets; n; n = n -> next_sibling) {
debug ("Subnet %s", piaddr (n -> net));
debug (" netmask %s",
piaddr (n -> netmask));
}
for (l = s -> leases; l; l = l -> next) {
print_lease (l);
}
debug ("Last Lease:");
print_lease (s -> last_lease);
}
}

View File

@ -0,0 +1,347 @@
/* nit.c
Network Interface Tap (NIT) network interface code, by Ted Lemon
with one crucial tidbit of help from Stu Grossmen. */
/*
* Copyright (c) 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''. */
#ifndef lint
static char copyright[] =
"$Id: nit.c,v 1.15 1997/10/20 21:47:13 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE)
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <net/nit.h>
#include <net/nit_if.h>
#include <net/nit_pf.h>
#include <net/nit_buf.h>
#include <sys/stropts.h>
#include <net/packetfilt.h>
#include <netinet/in_systm.h>
#include "includes/netinet/ip.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
/* Reinitializes the specified interface after an address change. This
is not required for packet-filter APIs. */
#ifdef USE_NIT_SEND
void if_reinitialize_send (info)
struct interface_info *info;
{
}
#endif
#ifdef USE_NIT_RECEIVE
void if_reinitialize_receive (info)
struct interface_info *info;
{
}
#endif
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
mask. */
int if_register_nit (info)
struct interface_info *info;
{
int sock;
char filename[50];
struct ifreq ifr;
struct strioctl sio;
/* Open a NIT device */
sock = open ("/dev/nit", O_RDWR);
if (sock < 0)
error ("Can't open NIT device for %s: %m", info -> name);
/* Set the NIT device to point at this interface. */
sio.ic_cmd = NIOCBIND;
sio.ic_len = sizeof *(info -> ifp);
sio.ic_dp = (char *)(info -> ifp);
sio.ic_timout = INFTIM;
if (ioctl (sock, I_STR, &sio) < 0)
error ("Can't attach interface %s to nit device: %m",
info -> name);
/* Get the low-level address... */
sio.ic_cmd = SIOCGIFADDR;
sio.ic_len = sizeof ifr;
sio.ic_dp = (char *)&ifr;
sio.ic_timout = INFTIM;
if (ioctl (sock, I_STR, &sio) < 0)
error ("Can't get physical layer address for %s: %m",
info -> name);
/* XXX code below assumes ethernet interface! */
info -> hw_address.hlen = 6;
info -> hw_address.htype = ARPHRD_ETHER;
memcpy (info -> hw_address.haddr, ifr.ifr_ifru.ifru_addr.sa_data, 6);
if (ioctl (sock, I_PUSH, "pf") < 0)
error ("Can't push packet filter onto NIT for %s: %m",
info -> name);
return sock;
}
#endif /* USE_NIT_SEND || USE_NIT_RECEIVE */
#ifdef USE_NIT_SEND
void if_register_send (info)
struct interface_info *info;
{
/* If we're using the nit API for sending and receiving,
we don't need to register this interface twice. */
#ifndef USE_NIT_RECEIVE
struct packetfilt pf;
struct strioctl sio;
info -> wfdesc = if_register_nit (info);
pf.Pf_Priority = 0;
pf.Pf_FilterLen = 1;
pf.Pf_Filter [0] = ENF_PUSHZERO;
/* Set up an NIT filter that rejects everything... */
sio.ic_cmd = NIOCSETF;
sio.ic_len = sizeof pf;
sio.ic_dp = (char *)&pf;
sio.ic_timout = INFTIM;
if (ioctl (info -> wfdesc, I_STR, &sio) < 0)
error ("Can't set NIT filter: %m");
#else
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on NIT/%s/%s",
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_NIT_SEND */
#ifdef USE_NIT_RECEIVE
/* Packet filter program...
XXX Changes to the filter program may require changes to the constant
offsets used in if_register_send to patch the NIT program! XXX */
void if_register_receive (info)
struct interface_info *info;
{
int flag = 1;
u_int32_t x;
struct packetfilt pf;
struct strioctl sio;
u_int16_t addr [2];
struct timeval t;
/* Open a NIT device and hang it on this interface... */
info -> rfdesc = if_register_nit (info);
/* Set the snap length to 0, which means always take the whole
packet. */
x = 0;
if (ioctl (info -> rfdesc, NIOCSSNAP, &x) < 0)
error ("Can't set NIT snap length on %s: %m", info -> name);
/* Set the stream to byte stream mode */
if (ioctl (info -> rfdesc, I_SRDOPT, RMSGN) != 0)
note ("I_SRDOPT failed on %s: %m", info -> name);
#if 0
/* Push on the chunker... */
if (ioctl (info -> rfdesc, I_PUSH, "nbuf") < 0)
error ("Can't push chunker onto NIT STREAM: %m");
/* Set the timeout to zero. */
t.tv_sec = 0;
t.tv_usec = 0;
if (ioctl (info -> rfdesc, NIOCSTIME, &t) < 0)
error ("Can't set chunk timeout: %m");
#endif
/* Ask for no header... */
x = 0;
if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0)
error ("Can't set NIT flags on %s: %m", info -> name);
/* Set up the NIT filter program. */
/* XXX Unlike the BPF filter program, this one won't work if the
XXX IP packet is fragmented or if there are options on the IP
XXX header. */
pf.Pf_Priority = 0;
pf.Pf_FilterLen = 0;
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 6;
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
pf.Pf_Filter [pf.Pf_FilterLen++] = htons (ETHERTYPE_IP);
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT;
pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP);
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 11;
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0xFF);
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_CAND;
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 18;
pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
pf.Pf_Filter [pf.Pf_FilterLen++] = local_port;
/* Install the filter... */
sio.ic_cmd = NIOCSETF;
sio.ic_len = sizeof pf;
sio.ic_dp = (char *)&pf;
sio.ic_timout = INFTIM;
if (ioctl (info -> rfdesc, I_STR, &sio) < 0)
error ("Can't set NIT filter on %s: %m", info -> name);
if (!quiet_interface_discovery)
note ("Listening on NIT/%s/%s",
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_NIT_RECEIVE */
#ifdef USE_NIT_SEND
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
struct dhcp_packet *raw;
size_t len;
struct in_addr from;
struct sockaddr_in *to;
struct hardware *hto;
{
int bufp;
unsigned char buf [1536 + sizeof (struct sockaddr)];
struct sockaddr *junk;
struct strbuf ctl, data;
int hw_end;
struct sockaddr_in foo;
/* Start with the sockaddr struct... */
junk = (struct sockaddr *)&buf [0];
bufp = ((unsigned char *)&junk -> sa_data [0]) - &buf [0];
/* Assemble the headers... */
assemble_hw_header (interface, buf, &bufp, hto);
hw_end = bufp;
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
raw, len);
/* Copy the data into the buffer (yuk). */
memcpy (buf + bufp, raw, len);
/* Set up the sockaddr structure... */
#if USE_SIN_LEN
junk -> sa_len = hw_end - 2; /* XXX */
#endif
junk -> sa_family = AF_UNSPEC;
#if 0 /* Already done. */
memcpy (junk.sa_data, buf, hw_len);
#endif
/* Set up the msg_buf structure... */
ctl.buf = (char *)&buf [0];
ctl.maxlen = ctl.len = hw_end;
data.buf = (char *)&buf [hw_end];
data.maxlen = data.len = bufp + len - hw_end;
return putmsg (interface -> wfdesc, &ctl, &data, 0);
}
#endif /* USE_NIT_SEND */
#ifdef USE_NIT_RECEIVE
ssize_t receive_packet (interface, buf, len, from, hfrom)
struct interface_info *interface;
unsigned char *buf;
size_t len;
struct sockaddr_in *from;
struct hardware *hfrom;
{
int nread;
int length = 0;
int offset = 0;
unsigned char ibuf [1536];
int bufix = 0;
length = read (interface -> rfdesc, ibuf, sizeof ibuf);
if (length <= 0)
return length;
/* Decode the physical header... */
offset = decode_hw_header (interface, ibuf, bufix, hfrom);
/* If a physical layer checksum failed (dunno of any
physical layer that supports this, but WTH), skip this
packet. */
if (offset < 0) {
return 0;
}
bufix += offset;
length -= offset;
/* Decode the IP and UDP headers... */
offset = decode_udp_ip_header (interface, ibuf, bufix,
from, (unsigned char *)0, length);
/* If the IP or UDP checksum was bad, skip the packet... */
if (offset < 0)
return 0;
bufix += offset;
length -= offset;
/* Copy out the data in the packet... */
memcpy (buf, &ibuf [bufix], length);
return length;
}
#endif

View File

@ -0,0 +1,609 @@
/* options.c
DHCP options parsing and reassembly. */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: options.c,v 1.26.2.3 1998/06/25 21:11:30 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#define DHCP_OPTION_DATA
#include "dhcpd.h"
/* Parse all available options out of the specified packet. */
void parse_options (packet)
struct packet *packet;
{
/* Initially, zero all option pointers. */
memset (packet -> options, 0, sizeof (packet -> options));
/* If we don't see the magic cookie, there's nothing to parse. */
if (memcmp (packet -> raw -> options, DHCP_OPTIONS_COOKIE, 4)) {
packet -> options_valid = 0;
return;
}
/* Go through the options field, up to the end of the packet
or the End field. */
parse_option_buffer (packet, &packet -> raw -> options [4],
packet -> packet_length - DHCP_FIXED_NON_UDP - 4);
/* If we parsed a DHCP Option Overload option, parse more
options out of the buffer(s) containing them. */
if (packet -> options_valid
&& packet -> options [DHO_DHCP_OPTION_OVERLOAD].data) {
if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 1)
parse_option_buffer (packet,
(unsigned char *)
packet -> raw -> file,
sizeof packet -> raw -> file);
if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)
parse_option_buffer (packet,
(unsigned char *)
packet -> raw -> sname,
sizeof packet -> raw -> sname);
}
}
/* Parse options out of the specified buffer, storing addresses of option
values in packet -> options and setting packet -> options_valid if no
errors are encountered. */
void parse_option_buffer (packet, buffer, length)
struct packet *packet;
unsigned char *buffer;
int length;
{
unsigned char *s, *t;
unsigned char *end = buffer + length;
int len;
int code;
for (s = buffer; *s != DHO_END && s < end; ) {
code = s [0];
/* Pad options don't have a length - just skip them. */
if (code == DHO_PAD) {
++s;
continue;
}
/* All other fields (except end, see above) have a
one-byte length. */
len = s [1];
/* If the length is outrageous, the options are bad. */
if (s + len + 2 > end) {
warn ("Option %s length %d overflows input buffer.",
dhcp_options [code].name,
len);
packet -> options_valid = 0;
return;
}
/* If we haven't seen this option before, just make
space for it and copy it there. */
if (!packet -> options [code].data) {
if (!(t = (unsigned char *)malloc (len + 1)))
error ("Can't allocate storage for option %s.",
dhcp_options [code].name);
/* Copy and NUL-terminate the option (in case it's an
ASCII string. */
memcpy (t, &s [2], len);
t [len] = 0;
packet -> options [code].len = len;
packet -> options [code].data = t;
} else {
/* If it's a repeat, concatenate it to whatever
we last saw. This is really only required
for clients, but what the heck... */
t = (unsigned char *)
malloc (len
+ packet -> options [code].len
+ 1);
if (!t)
error ("Can't expand storage for option %s.",
dhcp_options [code].name);
memcpy (t, packet -> options [code].data,
packet -> options [code].len);
memcpy (t + packet -> options [code].len,
&s [2], len);
packet -> options [code].len += len;
t [packet -> options [code].len] = 0;
free (packet -> options [code].data);
packet -> options [code].data = t;
}
s += len + 2;
}
packet -> options_valid = 1;
}
/* cons options into a big buffer, and then split them out into the
three seperate buffers if needed. This allows us to cons up a set
of vendor options using the same routine. */
int cons_options (inpacket, outpacket, options, overload, terminate, bootpp)
struct packet *inpacket;
struct dhcp_packet *outpacket;
struct tree_cache **options;
int overload; /* Overload flags that may be set. */
int terminate;
int bootpp;
{
unsigned char priority_list [300];
int priority_len;
unsigned char buffer [4096]; /* Really big buffer... */
int main_buffer_size;
int mainbufix, bufix;
int option_size;
int length;
/* If the client has provided a maximum DHCP message size,
use that; otherwise, if it's BOOTP, only 64 bytes; otherwise
use up to the minimum IP MTU size (576 bytes). */
/* XXX if a BOOTP client specifies a max message size, we will
honor it. */
if (inpacket && inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data) {
main_buffer_size =
(getUShort (inpacket -> options
[DHO_DHCP_MAX_MESSAGE_SIZE].data)
- DHCP_FIXED_LEN);
/* Enforce a minimum packet size... */
if (main_buffer_size < (576 - DHCP_FIXED_LEN))
main_buffer_size = 576 - DHCP_FIXED_LEN;
if (main_buffer_size > sizeof buffer)
main_buffer_size = sizeof buffer;
} else if (bootpp)
main_buffer_size = 64;
else
main_buffer_size = 576 - DHCP_FIXED_LEN;
/* Preload the option priority list with mandatory options. */
priority_len = 0;
priority_list [priority_len++] = DHO_DHCP_MESSAGE_TYPE;
priority_list [priority_len++] = DHO_DHCP_SERVER_IDENTIFIER;
priority_list [priority_len++] = DHO_DHCP_LEASE_TIME;
priority_list [priority_len++] = DHO_DHCP_MESSAGE;
/* If the client has provided a list of options that it wishes
returned, use it to prioritize. Otherwise, prioritize
based on the default priority list. */
if (inpacket &&
inpacket -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
int prlen = (inpacket ->
options [DHO_DHCP_PARAMETER_REQUEST_LIST].len);
if (prlen + priority_len > sizeof priority_list)
prlen = (sizeof priority_list) - priority_len;
memcpy (&priority_list [priority_len],
inpacket -> options
[DHO_DHCP_PARAMETER_REQUEST_LIST].data, prlen);
priority_len += prlen;
} else {
memcpy (&priority_list [priority_len],
dhcp_option_default_priority_list,
sizeof_dhcp_option_default_priority_list);
priority_len += sizeof_dhcp_option_default_priority_list;
}
/* Copy the options into the big buffer... */
option_size = store_options (buffer,
(main_buffer_size - 7 +
((overload & 1) ? DHCP_FILE_LEN : 0) +
((overload & 2) ? DHCP_SNAME_LEN : 0)),
options, priority_list, priority_len,
main_buffer_size,
(main_buffer_size +
((overload & 1) ? DHCP_FILE_LEN : 0)),
terminate);
/* Put the cookie up front... */
memcpy (outpacket -> options, DHCP_OPTIONS_COOKIE, 4);
mainbufix = 4;
/* If we're going to have to overload, store the overload
option at the beginning. If we can, though, just store the
whole thing in the packet's option buffer and leave it at
that. */
if (option_size <= main_buffer_size - mainbufix) {
memcpy (&outpacket -> options [mainbufix],
buffer, option_size);
mainbufix += option_size;
if (mainbufix < main_buffer_size)
outpacket -> options [mainbufix++]
= DHO_END;
length = DHCP_FIXED_NON_UDP + mainbufix;
} else {
outpacket -> options [mainbufix++] =
DHO_DHCP_OPTION_OVERLOAD;
outpacket -> options [mainbufix++] = 1;
if (option_size > main_buffer_size - mainbufix + DHCP_FILE_LEN)
outpacket -> options [mainbufix++] = 3;
else
outpacket -> options [mainbufix++] = 1;
memcpy (&outpacket -> options [mainbufix],
buffer, main_buffer_size - mainbufix);
bufix = main_buffer_size - mainbufix;
length = DHCP_FIXED_NON_UDP + mainbufix;
if (overload & 1) {
if (option_size - bufix <= DHCP_FILE_LEN) {
memcpy (outpacket -> file,
&buffer [bufix], option_size - bufix);
mainbufix = option_size - bufix;
if (mainbufix < DHCP_FILE_LEN)
outpacket -> file [mainbufix++]
= DHO_END;
while (mainbufix < DHCP_FILE_LEN)
outpacket -> file [mainbufix++]
= DHO_PAD;
} else {
memcpy (outpacket -> file,
&buffer [bufix], DHCP_FILE_LEN);
bufix += DHCP_FILE_LEN;
}
}
if ((overload & 2) && option_size < bufix) {
memcpy (outpacket -> sname,
&buffer [bufix], option_size - bufix);
mainbufix = option_size - bufix;
if (mainbufix < DHCP_SNAME_LEN)
outpacket -> file [mainbufix++]
= DHO_END;
while (mainbufix < DHCP_SNAME_LEN)
outpacket -> file [mainbufix++]
= DHO_PAD;
}
}
return length;
}
/* Store all the requested options into the requested buffer. */
int store_options (buffer, buflen, options, priority_list, priority_len,
first_cutoff, second_cutoff, terminate)
unsigned char *buffer;
int buflen;
struct tree_cache **options;
unsigned char *priority_list;
int priority_len;
int first_cutoff, second_cutoff;
int terminate;
{
int bufix = 0;
int option_stored [256];
int i;
int ix;
int tto;
/* Zero out the stored-lengths array. */
memset (option_stored, 0, sizeof option_stored);
/* Copy out the options in the order that they appear in the
priority list... */
for (i = 0; i < priority_len; i++) {
/* Code for next option to try to store. */
int code = priority_list [i];
int optstart;
/* Number of bytes left to store (some may already
have been stored by a previous pass). */
int length;
/* If no data is available for this option, skip it. */
if (!options [code]) {
continue;
}
/* The client could ask for things that are mandatory,
in which case we should avoid storing them twice... */
if (option_stored [code])
continue;
option_stored [code] = 1;
/* Find the value of the option... */
if (!tree_evaluate (options [code])) {
continue;
}
/* We should now have a constant length for the option. */
length = options [code] -> len;
/* Do we add a NUL? */
if (terminate && dhcp_options [code].format [0] == 't') {
length++;
tto = 1;
} else {
tto = 0;
}
/* Try to store the option. */
/* If the option's length is more than 255, we must store it
in multiple hunks. Store 255-byte hunks first. However,
in any case, if the option data will cross a buffer
boundary, split it across that boundary. */
ix = 0;
optstart = bufix;
while (length) {
unsigned char incr = length > 255 ? 255 : length;
/* If this hunk of the buffer will cross a
boundary, only go up to the boundary in this
pass. */
if (bufix < first_cutoff &&
bufix + incr > first_cutoff)
incr = first_cutoff - bufix;
else if (bufix < second_cutoff &&
bufix + incr > second_cutoff)
incr = second_cutoff - bufix;
/* If this option is going to overflow the buffer,
skip it. */
if (bufix + 2 + incr > buflen) {
bufix = optstart;
break;
}
/* Everything looks good - copy it in! */
buffer [bufix] = code;
buffer [bufix + 1] = incr;
if (tto && incr == length) {
memcpy (buffer + bufix + 2,
options [code] -> value + ix,
incr - 1);
buffer [bufix + 2 + incr - 1] = 0;
} else {
memcpy (buffer + bufix + 2,
options [code] -> value + ix, incr);
}
length -= incr;
ix += incr;
bufix += 2 + incr;
}
}
return bufix;
}
/* Format the specified option so that a human can easily read it. */
char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
unsigned int code;
unsigned char *data;
int len;
int emit_commas;
int emit_quotes;
{
static char optbuf [32768]; /* XXX */
int hunksize = 0;
int numhunk = -1;
int numelem = 0;
char fmtbuf [32];
int i, j;
char *op = optbuf;
unsigned char *dp = data;
struct in_addr foo;
char comma;
/* Code should be between 0 and 255. */
if (code > 255)
error ("pretty_print_option: bad code %d\n", code);
if (emit_commas)
comma = ',';
else
comma = ' ';
/* Figure out the size of the data. */
for (i = 0; dhcp_options [code].format [i]; i++) {
if (!numhunk) {
warn ("%s: Excess information in format string: %s\n",
dhcp_options [code].name,
&(dhcp_options [code].format [i]));
break;
}
numelem++;
fmtbuf [i] = dhcp_options [code].format [i];
switch (dhcp_options [code].format [i]) {
case 'A':
--numelem;
fmtbuf [i] = 0;
numhunk = 0;
break;
case 'X':
fmtbuf [i] = 'x';
fmtbuf [i + 1] = 0;
hunksize++;
numhunk = 0;
comma = ':';
break;
case 't':
fmtbuf [i] = 't';
fmtbuf [i + 1] = 0;
numhunk = -2;
break;
case 'I':
case 'l':
case 'L':
hunksize += 4;
break;
case 's':
case 'S':
hunksize += 2;
break;
case 'b':
case 'B':
case 'f':
hunksize++;
break;
case 'e':
break;
default:
warn ("%s: garbage in format string: %s\n",
dhcp_options [code].name,
&(dhcp_options [code].format [i]));
break;
}
}
/* Check for too few bytes... */
if (hunksize > len) {
warn ("%s: expecting at least %d bytes; got %d",
dhcp_options [code].name,
hunksize, len);
return "<error>";
}
/* Check for too many bytes... */
if (numhunk == -1 && hunksize < len)
warn ("%s: %d extra bytes",
dhcp_options [code].name,
len - hunksize);
/* If this is an array, compute its size. */
if (!numhunk)
numhunk = len / hunksize;
/* See if we got an exact number of hunks. */
if (numhunk > 0 && numhunk * hunksize < len)
warn ("%s: %d extra bytes at end of array\n",
dhcp_options [code].name,
len - numhunk * hunksize);
/* A one-hunk array prints the same as a single hunk. */
if (numhunk < 0)
numhunk = 1;
/* Cycle through the array (or hunk) printing the data. */
for (i = 0; i < numhunk; i++) {
for (j = 0; j < numelem; j++) {
switch (fmtbuf [j]) {
case 't':
if (emit_quotes)
*op++ = '"';
strcpy (op, (char *)dp);
op += strlen ((char *)dp);
if (emit_quotes)
*op++ = '"';
*op = 0;
break;
case 'I':
foo.s_addr = htonl (getULong (dp));
strcpy (op, inet_ntoa (foo));
dp += 4;
break;
case 'l':
sprintf (op, "%ld", (long)getLong (dp));
dp += 4;
break;
case 'L':
sprintf (op, "%ld",
(unsigned long)getULong (dp));
dp += 4;
break;
case 's':
sprintf (op, "%d", getShort (dp));
dp += 2;
break;
case 'S':
sprintf (op, "%d", getUShort (dp));
dp += 2;
break;
case 'b':
sprintf (op, "%d", *(char *)dp++);
break;
case 'B':
sprintf (op, "%d", *dp++);
break;
case 'x':
sprintf (op, "%x", *dp++);
break;
case 'f':
strcpy (op, *dp++ ? "true" : "false");
break;
default:
warn ("Unexpected format code %c", fmtbuf [j]);
}
op += strlen (op);
if (j + 1 < numelem && comma != ':')
*op++ = ' ';
}
if (i + 1 < numhunk) {
*op++ = comma;
}
}
return optbuf;
}
void do_packet (interface, packet, len, from_port, from, hfrom)
struct interface_info *interface;
struct dhcp_packet *packet;
int len;
unsigned int from_port;
struct iaddr from;
struct hardware *hfrom;
{
struct packet tp;
if (packet -> hlen > sizeof packet -> chaddr) {
note ("Discarding packet with invalid hlen.");
return;
}
memset (&tp, 0, sizeof tp);
tp.raw = packet;
tp.packet_length = len;
tp.client_port = from_port;
tp.client_addr = from;
tp.interface = interface;
tp.haddr = hfrom;
parse_options (&tp);
if (tp.options_valid &&
tp.options [DHO_DHCP_MESSAGE_TYPE].data)
tp.packet_type =
tp.options [DHO_DHCP_MESSAGE_TYPE].data [0];
if (tp.packet_type)
dhcp (&tp);
else
bootp (&tp);
}

View File

@ -0,0 +1,311 @@
/* packet.c
Packet assembly code, originally contributed by Archie Cobbs. */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: packet.c,v 1.18.2.1 1998/06/26 18:20:44 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#if defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING)
#include "includes/netinet/ip.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
/* Compute the easy part of the checksum on a range of bytes. */
u_int32_t checksum (buf, nbytes, sum)
unsigned char *buf;
int nbytes;
u_int32_t sum;
{
int i;
#ifdef DEBUG_CHECKSUM
debug ("checksum (%x %d %x)", buf, nbytes, sum);
#endif
/* Checksum all the pairs of bytes first... */
for (i = 0; i < (nbytes & ~1); i += 2) {
#ifdef DEBUG_CHECKSUM_VERBOSE
debug ("sum = %x", sum);
#endif
sum += (u_int16_t) ntohs(*((u_int16_t *)(buf + i)));
}
/* If there's a single byte left over, checksum it, too. Network
byte order is big-endian, so the remaining byte is the high byte. */
if (i < nbytes) {
#ifdef DEBUG_CHECKSUM_VERBOSE
debug ("sum = %x", sum);
#endif
sum += buf [i] << 8;
}
return sum;
}
/* Fold the upper sixteen bits of the checksum down into the lower bits,
complement the sum, and then put it into network byte order. */
u_int32_t wrapsum (sum)
u_int32_t sum;
{
#ifdef DEBUG_CHECKSUM
debug ("wrapsum (%x)", sum);
#endif
while (sum > 0x10000) {
sum = (sum >> 16) + (sum & 0xFFFF);
#ifdef DEBUG_CHECKSUM_VERBOSE
debug ("sum = %x", sum);
#endif
sum += (sum >> 16);
#ifdef DEBUG_CHECKSUM_VERBOSE
debug ("sum = %x", sum);
#endif
}
sum = sum ^ 0xFFFF;
#ifdef DEBUG_CHECKSUM_VERBOSE
debug ("sum = %x", sum);
#endif
#ifdef DEBUG_CHECKSUM
debug ("wrapsum returns %x", htons (sum));
#endif
return htons(sum);
}
#ifdef PACKET_ASSEMBLY
/* Assemble an hardware header... */
/* XXX currently only supports ethernet; doesn't check for other types. */
void assemble_hw_header (interface, buf, bufix, to)
struct interface_info *interface;
unsigned char *buf;
int *bufix;
struct hardware *to;
{
struct ether_header eh;
if (to && to -> hlen == 6) /* XXX */
memcpy (eh.ether_dhost, to -> haddr, sizeof eh.ether_dhost);
else
memset (eh.ether_dhost, 0xff, sizeof (eh.ether_dhost));
if (interface -> hw_address.hlen == sizeof (eh.ether_shost))
memcpy (eh.ether_shost, interface -> hw_address.haddr,
sizeof (eh.ether_shost));
else
memset (eh.ether_shost, 0x00, sizeof (eh.ether_shost));
#ifdef BROKEN_FREEBSD_BPF /* Fixed in FreeBSD 2.2 */
eh.ether_type = ETHERTYPE_IP;
#else
eh.ether_type = htons (ETHERTYPE_IP);
#endif
memcpy (&buf [*bufix], &eh, sizeof eh);
*bufix += sizeof eh;
}
/* UDP header and IP header assembled together for convenience. */
void assemble_udp_ip_header (interface, buf, bufix,
from, to, port, data, len)
struct interface_info *interface;
unsigned char *buf;
int *bufix;
u_int32_t from;
u_int32_t to;
unsigned int port;
unsigned char *data;
int len;
{
struct ip ip;
struct udphdr udp;
/* Fill out the IP header */
ip.ip_v = 4;
ip.ip_hl = 5;
ip.ip_tos = IPTOS_LOWDELAY;
ip.ip_len = htons(sizeof(ip) + sizeof(udp) + len);
ip.ip_id = 0;
ip.ip_off = 0;
ip.ip_ttl = 16;
ip.ip_p = IPPROTO_UDP;
ip.ip_sum = 0;
ip.ip_src.s_addr = from;
ip.ip_dst.s_addr = to;
/* Checksum the IP header... */
ip.ip_sum = wrapsum (checksum ((unsigned char *)&ip, sizeof ip, 0));
/* Copy the ip header into the buffer... */
memcpy (&buf [*bufix], &ip, sizeof ip);
*bufix += sizeof ip;
/* Fill out the UDP header */
udp.uh_sport = local_port; /* XXX */
udp.uh_dport = port; /* XXX */
udp.uh_ulen = htons(sizeof(udp) + len);
memset (&udp.uh_sum, 0, sizeof udp.uh_sum);
/* Compute UDP checksums, including the ``pseudo-header'', the UDP
header and the data. */
#if 0
udp.uh_sum =
wrapsum (checksum ((unsigned char *)&udp, sizeof udp,
checksum (data, len,
checksum ((unsigned char *)
&ip.ip_src,
sizeof ip.ip_src,
IPPROTO_UDP +
(u_int32_t)
ntohs (udp.uh_ulen)))));
#endif
/* Copy the udp header into the buffer... */
memcpy (&buf [*bufix], &udp, sizeof udp);
*bufix += sizeof udp;
}
#endif /* PACKET_ASSEMBLY */
#ifdef PACKET_DECODING
/* Decode a hardware header... */
/* XXX currently only supports ethernet; doesn't check for other types. */
ssize_t decode_hw_header (interface, buf, bufix, from)
struct interface_info *interface;
unsigned char *buf;
int bufix;
struct hardware *from;
{
struct ether_header eh;
memcpy (&eh, buf + bufix, sizeof eh);
#ifdef USERLAND_FILTER
if (ntohs (eh.ether_type) != ETHERTYPE_IP)
return -1;
#endif
memcpy (from -> haddr, eh.ether_shost, sizeof (eh.ether_shost));
from -> htype = ARPHRD_ETHER;
from -> hlen = sizeof eh.ether_shost;
return sizeof eh;
}
/* UDP header and IP header decoded together for convenience. */
ssize_t decode_udp_ip_header (interface, buf, bufix, from, data, len)
struct interface_info *interface;
unsigned char *buf;
int bufix;
struct sockaddr_in *from;
unsigned char *data;
int len;
{
struct ip *ip;
struct udphdr *udp;
u_int32_t ip_len = (buf [bufix] & 0xf) << 2;
u_int32_t sum, usum;
ip = (struct ip *)(buf + bufix);
udp = (struct udphdr *)(buf + bufix + ip_len);
#ifdef USERLAND_FILTER
/* Is it a UDP packet? */
if (ip -> ip_p != IPPROTO_UDP)
return -1;
/* Is it to the port we're serving? */
if (udp -> uh_dport != local_port)
return -1;
#endif /* USERLAND_FILTER */
/* Check the IP header checksum - it should be zero. */
if (wrapsum (checksum (buf + bufix, ip_len, 0))) {
note ("Bad IP checksum: %x",
wrapsum (checksum (buf + bufix, sizeof *ip, 0)));
return -1;
}
/* Copy out the IP source address... */
memcpy (&from -> sin_addr, &ip -> ip_src, 4);
/* Compute UDP checksums, including the ``pseudo-header'', the UDP
header and the data. If the UDP checksum field is zero, we're
not supposed to do a checksum. */
if (!data) {
data = buf + bufix + ip_len + sizeof *udp;
len -= ip_len + sizeof *udp;
}
#if 0
usum = udp -> uh_sum;
udp -> uh_sum = 0;
sum = wrapsum (checksum ((unsigned char *)udp, sizeof *udp,
checksum (data, len,
checksum ((unsigned char *)
&ip -> ip_src,
sizeof ip -> ip_src,
IPPROTO_UDP +
(u_int32_t)
ntohs (udp -> uh_ulen)))));
if (usum && usum != sum) {
note ("Bad udp checksum: %x %x", usum, sum);
return -1;
}
#endif
/* Copy out the port... */
memcpy (&from -> sin_port, &udp -> uh_sport, sizeof udp -> uh_sport);
return ip_len + sizeof *udp;
}
#endif /* PACKET_DECODING */

View File

@ -0,0 +1,643 @@
/* parse.c
Common parser code for dhcpd and dhclient. */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: parse.c,v 1.2.2.1 1998/06/25 21:11:31 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "dhctoken.h"
/* Skip to the semicolon ending the current statement. If we encounter
braces, the matching closing brace terminates the statement. If we
encounter a right brace but haven't encountered a left brace, return
leaving the brace in the token buffer for the caller. If we see a
semicolon and haven't seen a left brace, return. This lets us skip
over:
statement;
statement foo bar { }
statement foo bar { statement { } }
statement}
...et cetera. */
void skip_to_semi (cfile)
FILE *cfile;
{
int token;
char *val;
int brace_count = 0;
do {
token = peek_token (&val, cfile);
if (token == RBRACE) {
if (brace_count) {
token = next_token (&val, cfile);
if (!--brace_count)
return;
} else
return;
} else if (token == LBRACE) {
brace_count++;
} else if (token == SEMI && !brace_count) {
token = next_token (&val, cfile);
return;
} else if (token == EOL) {
/* EOL only happens when parsing /etc/resolv.conf,
and we treat it like a semicolon because the
resolv.conf file is line-oriented. */
token = next_token (&val, cfile);
return;
}
token = next_token (&val, cfile);
} while (token != EOF);
}
int parse_semi (cfile)
FILE *cfile;
{
int token;
char *val;
token = next_token (&val, cfile);
if (token != SEMI) {
parse_warn ("semicolon expected.");
skip_to_semi (cfile);
return 0;
}
return 1;
}
/* string-parameter :== STRING SEMI */
char *parse_string (cfile)
FILE *cfile;
{
char *val;
int token;
char *s;
token = next_token (&val, cfile);
if (token != STRING) {
parse_warn ("filename must be a string");
skip_to_semi (cfile);
return (char *)0;
}
s = (char *)malloc (strlen (val) + 1);
if (!s)
error ("no memory for string %s.", val);
strcpy (s, val);
if (!parse_semi (cfile))
return (char *)0;
return s;
}
/* hostname :== identifier | hostname DOT identifier */
char *parse_host_name (cfile)
FILE *cfile;
{
char *val;
int token;
int len = 0;
char *s;
char *t;
pair c = (pair)0;
/* Read a dotted hostname... */
do {
/* Read a token, which should be an identifier. */
token = next_token (&val, cfile);
if (!is_identifier (token) && token != NUMBER) {
parse_warn ("expecting an identifier in hostname");
skip_to_semi (cfile);
return (char *)0;
}
/* Store this identifier... */
if (!(s = (char *)malloc (strlen (val) + 1)))
error ("can't allocate temp space for hostname.");
strcpy (s, val);
c = cons ((caddr_t)s, c);
len += strlen (s) + 1;
/* Look for a dot; if it's there, keep going, otherwise
we're done. */
token = peek_token (&val, cfile);
if (token == DOT)
token = next_token (&val, cfile);
} while (token == DOT);
/* Assemble the hostname together into a string. */
if (!(s = (char *)malloc (len)))
error ("can't allocate space for hostname.");
t = s + len;
*--t = 0;
while (c) {
pair cdr = c -> cdr;
int l = strlen ((char *)(c -> car));
t -= l;
memcpy (t, (char *)(c -> car), l);
/* Free up temp space. */
free (c -> car);
free (c);
c = cdr;
if (t != s)
*--t = '.';
}
return s;
}
int parse_ip_addr (cfile, addr)
FILE *cfile;
struct iaddr *addr;
{
char *val;
int token;
addr -> len = 4;
if (parse_numeric_aggregate (cfile, addr -> iabuf,
&addr -> len, DOT, 10, 8))
return 1;
return 0;
}
/* hardware-parameter :== HARDWARE ETHERNET csns SEMI
csns :== NUMBER | csns COLON NUMBER */
void parse_hardware_param (cfile, hardware)
FILE *cfile;
struct hardware *hardware;
{
char *val;
int token;
int hlen;
unsigned char *t;
token = next_token (&val, cfile);
switch (token) {
case ETHERNET:
hardware -> htype = HTYPE_ETHER;
break;
case TOKEN_RING:
hardware -> htype = HTYPE_IEEE802;
break;
default:
parse_warn ("expecting a network hardware type");
skip_to_semi (cfile);
return;
}
/* Parse the hardware address information. Technically,
it would make a lot of sense to restrict the length of the
data we'll accept here to the length of a particular hardware
address type. Unfortunately, there are some broken clients
out there that put bogus data in the chaddr buffer, and we accept
that data in the lease file rather than simply failing on such
clients. Yuck. */
hlen = 0;
t = parse_numeric_aggregate (cfile, (unsigned char *)0, &hlen,
COLON, 16, 8);
if (!t)
return;
if (hlen > sizeof hardware -> haddr) {
free (t);
parse_warn ("hardware address too long");
} else {
hardware -> hlen = hlen;
memcpy ((unsigned char *)&hardware -> haddr [0],
t, hardware -> hlen);
free (t);
}
token = next_token (&val, cfile);
if (token != SEMI) {
parse_warn ("expecting semicolon.");
skip_to_semi (cfile);
}
}
/* lease-time :== NUMBER SEMI */
void parse_lease_time (cfile, timep)
FILE *cfile;
TIME *timep;
{
char *val;
int token;
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("Expecting numeric lease time");
skip_to_semi (cfile);
return;
}
convert_num ((unsigned char *)timep, val, 10, 32);
/* Unswap the number - convert_num returns stuff in NBO. */
*timep = ntohl (*timep); /* XXX */
parse_semi (cfile);
}
/* No BNF for numeric aggregates - that's defined by the caller. What
this function does is to parse a sequence of numbers seperated by
the token specified in seperator. If max is zero, any number of
numbers will be parsed; otherwise, exactly max numbers are
expected. Base and size tell us how to internalize the numbers
once they've been tokenized. */
unsigned char *parse_numeric_aggregate (cfile, buf,
max, seperator, base, size)
FILE *cfile;
unsigned char *buf;
int *max;
int seperator;
int base;
int size;
{
char *val;
int token;
unsigned char *bufp = buf, *s;
char *t;
int count = 0;
pair c = (pair)0;
if (!bufp && *max) {
bufp = (unsigned char *)malloc (*max * size / 8);
if (!bufp)
error ("can't allocate space for numeric aggregate");
} else
s = bufp;
do {
if (count) {
token = peek_token (&val, cfile);
if (token != seperator) {
if (!*max)
break;
if (token != RBRACE && token != LBRACE)
token = next_token (&val, cfile);
parse_warn ("too few numbers.");
if (token != SEMI)
skip_to_semi (cfile);
return (unsigned char *)0;
}
token = next_token (&val, cfile);
}
token = next_token (&val, cfile);
if (token == EOF) {
parse_warn ("unexpected end of file");
break;
}
/* Allow NUMBER_OR_NAME if base is 16. */
if (token != NUMBER &&
(base != 16 || token != NUMBER_OR_NAME)) {
parse_warn ("expecting numeric value.");
skip_to_semi (cfile);
return (unsigned char *)0;
}
/* If we can, convert the number now; otherwise, build
a linked list of all the numbers. */
if (s) {
convert_num (s, val, base, size);
s += size / 8;
} else {
t = (char *)malloc (strlen (val) + 1);
if (!t)
error ("no temp space for number.");
strcpy (t, val);
c = cons (t, c);
}
} while (++count != *max);
/* If we had to cons up a list, convert it now. */
if (c) {
bufp = (unsigned char *)malloc (count * size / 8);
if (!bufp)
error ("can't allocate space for numeric aggregate.");
s = bufp + count - size / 8;
*max = count;
}
while (c) {
pair cdr = c -> cdr;
convert_num (s, (char *)(c -> car), base, size);
s -= size / 8;
/* Free up temp space. */
free (c -> car);
free (c);
c = cdr;
}
return bufp;
}
void convert_num (buf, str, base, size)
unsigned char *buf;
char *str;
int base;
int size;
{
char *ptr = str;
int negative = 0;
u_int32_t val = 0;
int tval;
int max;
if (*ptr == '-') {
negative = 1;
++ptr;
}
/* If base wasn't specified, figure it out from the data. */
if (!base) {
if (ptr [0] == '0') {
if (ptr [1] == 'x') {
base = 16;
ptr += 2;
} else if (isascii (ptr [1]) && isdigit (ptr [1])) {
base = 8;
ptr += 1;
} else {
base = 10;
}
} else {
base = 10;
}
}
do {
tval = *ptr++;
/* XXX assumes ASCII... */
if (tval >= 'a')
tval = tval - 'a' + 10;
else if (tval >= 'A')
tval = tval - 'A' + 10;
else if (tval >= '0')
tval -= '0';
else {
warn ("Bogus number: %s.", str);
break;
}
if (tval >= base) {
warn ("Bogus number: %s: digit %d not in base %d\n",
str, tval, base);
break;
}
val = val * base + tval;
} while (*ptr);
if (negative)
max = (1 << (size - 1));
else
max = (1 << (size - 1)) + ((1 << (size - 1)) - 1);
if (val > max) {
switch (base) {
case 8:
warn ("value %s%o exceeds max (%d) for precision.",
negative ? "-" : "", val, max);
break;
case 16:
warn ("value %s%x exceeds max (%d) for precision.",
negative ? "-" : "", val, max);
break;
default:
warn ("value %s%u exceeds max (%d) for precision.",
negative ? "-" : "", val, max);
break;
}
}
if (negative) {
switch (size) {
case 8:
*buf = -(unsigned long)val;
break;
case 16:
putShort (buf, -(unsigned long)val);
break;
case 32:
putLong (buf, -(unsigned long)val);
break;
default:
warn ("Unexpected integer size: %d\n", size);
break;
}
} else {
switch (size) {
case 8:
*buf = (u_int8_t)val;
break;
case 16:
putUShort (buf, (u_int16_t)val);
break;
case 32:
putULong (buf, val);
break;
default:
warn ("Unexpected integer size: %d\n", size);
break;
}
}
}
/* date :== NUMBER NUMBER SLASH NUMBER SLASH NUMBER
NUMBER COLON NUMBER COLON NUMBER SEMI
Dates are always in GMT; first number is day of week; next is
year/month/day; next is hours:minutes:seconds on a 24-hour
clock. */
TIME parse_date (cfile)
FILE *cfile;
{
struct tm tm;
int guess;
char *val;
int token;
static int months [11] = { 31, 59, 90, 120, 151, 181,
212, 243, 273, 304, 334 };
/* Day of week... */
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("numeric day of week expected.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
tm.tm_wday = atoi (val);
/* Year... */
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("numeric year expected.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
tm.tm_year = atoi (val);
if (tm.tm_year > 1900)
tm.tm_year -= 1900;
/* Slash seperating year from month... */
token = next_token (&val, cfile);
if (token != SLASH) {
parse_warn ("expected slash seperating year from month.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
/* Month... */
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("numeric month expected.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
tm.tm_mon = atoi (val) - 1;
/* Slash seperating month from day... */
token = next_token (&val, cfile);
if (token != SLASH) {
parse_warn ("expected slash seperating month from day.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
/* Month... */
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("numeric day of month expected.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
tm.tm_mday = atoi (val);
/* Hour... */
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("numeric hour expected.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
tm.tm_hour = atoi (val);
/* Colon seperating hour from minute... */
token = next_token (&val, cfile);
if (token != COLON) {
parse_warn ("expected colon seperating hour from minute.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
/* Minute... */
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("numeric minute expected.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
tm.tm_min = atoi (val);
/* Colon seperating minute from second... */
token = next_token (&val, cfile);
if (token != COLON) {
parse_warn ("expected colon seperating hour from minute.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
/* Minute... */
token = next_token (&val, cfile);
if (token != NUMBER) {
parse_warn ("numeric minute expected.");
if (token != SEMI)
skip_to_semi (cfile);
return (TIME)0;
}
tm.tm_sec = atoi (val);
tm.tm_isdst = 0;
/* XXX */ /* We assume that mktime does not use tm_yday. */
tm.tm_yday = 0;
/* Make sure the date ends in a semicolon... */
token = next_token (&val, cfile);
if (token != SEMI) {
parse_warn ("semicolon expected.");
skip_to_semi (cfile);
return 0;
}
/* Guess the time value... */
guess = ((((((365 * (tm.tm_year - 70) + /* Days in years since '70 */
(tm.tm_year - 69) / 4 + /* Leap days since '70 */
(tm.tm_mon /* Days in months this year */
? months [tm.tm_mon - 1]
: 0) +
(tm.tm_mon > 1 && /* Leap day this year */
!((tm.tm_year - 72) & 3)) +
tm.tm_mday - 1) * 24) + /* Day of month */
tm.tm_hour) * 60) +
tm.tm_min) * 60) + tm.tm_sec;
/* This guess could be wrong because of leap seconds or other
weirdness we don't know about that the system does. For
now, we're just going to accept the guess, but at some point
it might be nice to do a successive approximation here to
get an exact value. Even if the error is small, if the
server is restarted frequently (and thus the lease database
is reread), the error could accumulate into something
significant. */
return guess;
}

View File

@ -0,0 +1,184 @@
/* print.c
Turn data structures into printable text. */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: print.c,v 1.16.2.1 1998/06/25 21:11:31 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
char *print_hw_addr (htype, hlen, data)
int htype;
int hlen;
unsigned char *data;
{
static char habuf [49];
char *s;
int i;
if (htype == 0 || hlen == 0) {
strcpy (habuf, "<null>");
} else {
s = habuf;
for (i = 0; i < hlen; i++) {
sprintf (s, "%02x", data [i]);
s += strlen (s);
*s++ = ':';
}
*--s = 0;
}
return habuf;
}
void print_lease (lease)
struct lease *lease;
{
struct tm *t;
char tbuf [32];
debug (" Lease %s",
piaddr (lease -> ip_addr));
t = gmtime (&lease -> starts);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
debug (" start %s", tbuf);
t = gmtime (&lease -> ends);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
debug (" end %s", tbuf);
t = gmtime (&lease -> timestamp);
strftime (tbuf, sizeof tbuf, "%D %H:%M:%S", t);
debug (" stamp %s", tbuf);
debug (" hardware addr = %s",
print_hw_addr (lease -> hardware_addr.htype,
lease -> hardware_addr.hlen,
lease -> hardware_addr.haddr));
debug (" host %s ",
lease -> host ? lease -> host -> name : "<none>");
}
void dump_packet (tp)
struct packet *tp;
{
struct dhcp_packet *tdp = tp -> raw;
debug ("packet length %d", tp -> packet_length);
debug ("op = %d htype = %d hlen = %d hops = %d",
tdp -> op, tdp -> htype, tdp -> hlen, tdp -> hops);
debug ("xid = %x secs = %d flags = %x",
tdp -> xid, tdp -> secs, tdp -> flags);
debug ("ciaddr = %s", inet_ntoa (tdp -> ciaddr));
debug ("yiaddr = %s", inet_ntoa (tdp -> yiaddr));
debug ("siaddr = %s", inet_ntoa (tdp -> siaddr));
debug ("giaddr = %s", inet_ntoa (tdp -> giaddr));
debug ("chaddr = %02.2x:%02.2x:%02.2x:%02.2x:%02.2x:%02.2x",
((unsigned char *)(tdp -> chaddr)) [0],
((unsigned char *)(tdp -> chaddr)) [1],
((unsigned char *)(tdp -> chaddr)) [2],
((unsigned char *)(tdp -> chaddr)) [3],
((unsigned char *)(tdp -> chaddr)) [4],
((unsigned char *)(tdp -> chaddr)) [5]);
debug ("filename = %s", tdp -> file);
debug ("server_name = %s", tdp -> sname);
if (tp -> options_valid) {
int i;
for (i = 0; i < 256; i++) {
if (tp -> options [i].data)
debug (" %s = %s",
dhcp_options [i].name,
pretty_print_option
(i, tp -> options [i].data,
tp -> options [i].len, 1, 1));
}
}
debug ("");
}
void dump_raw (buf, len)
unsigned char *buf;
int len;
{
int i;
char lbuf [80];
int lbix = 0;
lbuf [0] = 0;
for (i = 0; i < len; i++) {
if ((i & 15) == 0) {
if (lbix)
note (lbuf);
sprintf (lbuf, "%03x:", i);
lbix = 4;
} else if ((i & 7) == 0)
lbuf [lbix++] = ' ';
sprintf (&lbuf [lbix], " %02x", buf [i]);
lbix += 3;
}
note (lbuf);
}
void hash_dump (table)
struct hash_table *table;
{
int i;
struct hash_bucket *bp;
if (!table)
return;
for (i = 0; i < table -> hash_count; i++) {
if (!table -> buckets [i])
continue;
note ("hash bucket %d:", i);
for (bp = table -> buckets [i]; bp; bp = bp -> next) {
if (bp -> len)
dump_raw (bp -> name, bp -> len);
else
note ((char *)bp -> name);
}
}
}

View File

@ -0,0 +1,132 @@
/* socket.c
BSD raw socket interface code... */
/* XXX
It's not clear how this should work, and that lack of clarity is
terribly detrimental to the NetBSD 1.1 kernel - it crashes and
burns.
Using raw sockets ought to be a big win over using BPF or something
like it, because you don't need to deal with the complexities of
the physical layer, but it appears not to be possible with existing
raw socket implementations. This may be worth revisiting in the
future. For now, this code can probably be considered a curiosity.
Sigh. */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''. */
#ifndef lint
static char copyright[] =
"$Id: raw.c,v 1.11 1997/10/20 21:47:14 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#if defined (USE_RAW_SEND)
#include <sys/uio.h>
/* Generic interface registration routine... */
void if_register_send (info)
struct interface_info *info;
{
struct sockaddr_in name;
int sock;
struct socklist *tmp;
int flag;
/* Set up the address we're going to connect to. */
name.sin_family = AF_INET;
name.sin_port = local_port;
name.sin_addr.s_addr = htonl (INADDR_BROADCAST);
memset (name.sin_zero, 0, sizeof (name.sin_zero));
/* List addresses on which we're listening. */
if (!quiet_interface_discovery)
note ("Sending on %s, port %d",
piaddr (info -> address), htons (local_port));
if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
error ("Can't create dhcp socket: %m");
/* Set the BROADCAST option so that we can broadcast DHCP responses. */
flag = 1;
if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
&flag, sizeof flag) < 0)
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
/* Set the IP_HDRINCL flag so that we can supply our own IP
headers... */
if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0)
error ("Can't set IP_HDRINCL flag: %m");
info -> wfdesc = sock;
if (!quiet_interface_discovery)
note ("Sending on Raw/%s/%s",
info -> name,
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
size_t send_packet (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
struct dhcp_packet *raw;
size_t len;
struct in_addr from;
struct sockaddr_in *to;
struct hardware *hto;
{
unsigned char buf [256];
int bufp = 0;
struct iovec iov [2];
/* Assemble the headers... */
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
(unsigned char *)raw, len);
/* Fire it off */
iov [0].iov_base = (char *)buf;
iov [0].iov_len = bufp;
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
return writev(interface -> wfdesc, iov, 2);
}
#endif /* USE_SOCKET_SEND */

View File

@ -0,0 +1,256 @@
/* socket.c
BSD socket interface code... */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
/* SO_BINDTODEVICE support added by Elliot Poger (poger@leland.stanford.edu).
* This sockopt allows a socket to be bound to a particular interface,
* thus enabling the use of DHCPD on a multihomed host.
* If SO_BINDTODEVICE is defined in your system header files, the use of
* this sockopt will be automatically enabled.
* I have implemented it under Linux; other systems should be doable also.
*/
#ifndef lint
static char copyright[] =
"$Id: socket.c,v 1.26.2.2 1998/06/25 21:11:32 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#ifdef USE_SOCKET_FALLBACK
# define USE_SOCKET_SEND
# define if_register_send if_register_fallback
# define send_packet send_fallback
# define if_reinitialize_send if_reinitialize_fallback
#endif
static int once = 0;
/* Reinitializes the specified interface after an address change. This
is not required for packet-filter APIs. */
#ifdef USE_SOCKET_SEND
void if_reinitialize_send (info)
struct interface_info *info;
{
#if 0
#ifndef USE_SOCKET_RECEIVE
once = 0;
close (info -> wfdesc);
#endif
if_register_send (info);
#endif
}
#endif
#ifdef USE_SOCKET_RECEIVE
void if_reinitialize_receive (info)
struct interface_info *info;
{
#if 0
once = 0;
close (info -> rfdesc);
if_register_receive (info);
#endif
}
#endif
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE)
/* Generic interface registration routine... */
int if_register_socket (info)
struct interface_info *info;
{
struct sockaddr_in name;
int sock;
int flag;
#ifndef SO_BINDTODEVICE
/* Make sure only one interface is registered. */
if (once)
error ("The standard socket API can only support %s",
"hosts with a single network interface.");
once = 1;
#endif
/* Set up the address we're going to bind to. */
name.sin_family = AF_INET;
name.sin_port = local_port;
name.sin_addr.s_addr = INADDR_ANY;
memset (name.sin_zero, 0, sizeof (name.sin_zero));
/* Make a socket... */
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
error ("Can't create dhcp socket: %m");
/* Set the REUSEADDR option so that we don't fail to start if
we're being restarted. */
flag = 1;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&flag, sizeof flag) < 0)
error ("Can't set SO_REUSEADDR option on dhcp socket: %m");
/* Set the BROADCAST option so that we can broadcast DHCP responses. */
if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
(char *)&flag, sizeof flag) < 0)
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
/* Bind the socket to this interface's IP address. */
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
error ("Can't bind to dhcp address: %m");
#ifdef SO_BINDTODEVICE
/* Bind this socket to this interface. */
if (setsockopt (sock, SOL_SOCKET, SO_BINDTODEVICE,
(char *)(info -> ifp), sizeof *(info -> ifp)) < 0) {
error("setting SO_BINDTODEVICE");
}
#endif
return sock;
}
#endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE */
#ifdef USE_SOCKET_SEND
void if_register_send (info)
struct interface_info *info;
{
#ifndef USE_SOCKET_RECEIVE
info -> wfdesc = if_register_socket (info);
#else
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on Socket/%s/%s",
info -> name,
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_SOCKET_SEND */
#ifdef USE_SOCKET_RECEIVE
void if_register_receive (info)
struct interface_info *info;
{
/* If we're using the socket API for sending and receiving,
we don't need to register this interface twice. */
info -> rfdesc = if_register_socket (info);
if (!quiet_interface_discovery)
note ("Listening on Socket/%s/%s",
info -> name,
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_SOCKET_RECEIVE */
#ifdef USE_SOCKET_SEND
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
struct dhcp_packet *raw;
size_t len;
struct in_addr from;
struct sockaddr_in *to;
struct hardware *hto;
{
int result;
#ifdef IGNORE_HOSTUNREACH
int retry = 0;
do {
#endif
result = sendto (interface -> wfdesc, (char *)raw, len, 0,
(struct sockaddr *)to, sizeof *to);
#ifdef IGNORE_HOSTUNREACH
} while (to -> sin_addr.s_addr == htonl (INADDR_BROADCAST) &&
result < 0 &&
(errno == EHOSTUNREACH ||
errno == ECONNREFUSED) &&
retry++ < 10);
#endif
return result;
}
#endif /* USE_SOCKET_SEND */
#ifdef USE_SOCKET_RECEIVE
ssize_t receive_packet (interface, buf, len, from, hfrom)
struct interface_info *interface;
unsigned char *buf;
size_t len;
struct sockaddr_in *from;
struct hardware *hfrom;
{
int flen = sizeof *from;
int result;
#ifdef IGNORE_HOSTUNREACH
int retry = 0;
do {
#endif
result = recvfrom (interface -> rfdesc, (char *)buf, len, 0,
(struct sockaddr *)from, &flen);
#ifdef IGNORE_HOSTUNREACH
} while (result < 0 &&
(errno == EHOSTUNREACH ||
errno == ECONNREFUSED) &&
retry++ < 10);
#endif
return result;
}
#endif /* USE_SOCKET_RECEIVE */
#ifdef USE_SOCKET_FALLBACK
/* This just reads in a packet and silently discards it. */
void fallback_discard (protocol)
struct protocol *protocol;
{
char buf [1540];
struct sockaddr_in from;
int flen = sizeof from;
int status;
struct interface_info *interface = protocol -> local;
status = recvfrom (interface -> wfdesc, buf, sizeof buf, 0,
(struct sockaddr *)&from, &flen);
if (status < 0)
warn ("fallback_discard: %m");
}
#endif /* USE_SOCKET_RECEIVE */

View File

@ -0,0 +1,692 @@
/* tables.c
Tables of information... */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: tables.c,v 1.13.2.1 1998/06/25 21:11:32 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
/* DHCP Option names, formats and codes, from RFC1533.
Format codes:
e - end of data
I - IP address
l - 32-bit signed integer
L - 32-bit unsigned integer
s - 16-bit signed integer
S - 16-bit unsigned integer
b - 8-bit signed integer
B - 8-bit unsigned integer
t - ASCII text
f - flag (true or false)
A - array of whatever precedes (e.g., IA means array of IP addresses)
*/
struct universe dhcp_universe;
struct option dhcp_options [256] = {
{ "pad", "", &dhcp_universe, 0 },
{ "subnet-mask", "I", &dhcp_universe, 1 },
{ "time-offset", "l", &dhcp_universe, 2 },
{ "routers", "IA", &dhcp_universe, 3 },
{ "time-servers", "IA", &dhcp_universe, 4 },
{ "ien116-name-servers", "IA", &dhcp_universe, 5 },
{ "domain-name-servers", "IA", &dhcp_universe, 6 },
{ "log-servers", "IA", &dhcp_universe, 7 },
{ "cookie-servers", "IA", &dhcp_universe, 8 },
{ "lpr-servers", "IA", &dhcp_universe, 9 },
{ "impress-servers", "IA", &dhcp_universe, 10 },
{ "resource-location-servers", "IA", &dhcp_universe, 11 },
{ "host-name", "t", &dhcp_universe, 12 },
{ "boot-size", "S", &dhcp_universe, 13 },
{ "merit-dump", "t", &dhcp_universe, 14 },
{ "domain-name", "t", &dhcp_universe, 15 },
{ "swap-server", "I", &dhcp_universe, 16 },
{ "root-path", "t", &dhcp_universe, 17 },
{ "extensions-path", "t", &dhcp_universe, 18 },
{ "ip-forwarding", "f", &dhcp_universe, 19 },
{ "non-local-source-routing", "f", &dhcp_universe, 20 },
{ "policy-filter", "IIA", &dhcp_universe, 21 },
{ "max-dgram-reassembly", "S", &dhcp_universe, 22 },
{ "default-ip-ttl", "B", &dhcp_universe, 23 },
{ "path-mtu-aging-timeout", "L", &dhcp_universe, 24 },
{ "path-mtu-plateau-table", "SA", &dhcp_universe, 25 },
{ "interface-mtu", "S", &dhcp_universe, 26 },
{ "all-subnets-local", "f", &dhcp_universe, 27 },
{ "broadcast-address", "I", &dhcp_universe, 28 },
{ "perform-mask-discovery", "f", &dhcp_universe, 29 },
{ "mask-supplier", "f", &dhcp_universe, 30 },
{ "router-discovery", "f", &dhcp_universe, 31 },
{ "router-solicitation-address", "I", &dhcp_universe, 32 },
{ "static-routes", "IIA", &dhcp_universe, 33 },
{ "trailer-encapsulation", "f", &dhcp_universe, 34 },
{ "arp-cache-timeout", "L", &dhcp_universe, 35 },
{ "ieee802-3-encapsulation", "f", &dhcp_universe, 36 },
{ "default-tcp-ttl", "B", &dhcp_universe, 37 },
{ "tcp-keepalive-interval", "L", &dhcp_universe, 38 },
{ "tcp-keepalive-garbage", "f", &dhcp_universe, 39 },
{ "nis-domain", "t", &dhcp_universe, 40 },
{ "nis-servers", "IA", &dhcp_universe, 41 },
{ "ntp-servers", "IA", &dhcp_universe, 42 },
{ "vendor-encapsulated-options", "X", &dhcp_universe, 43 },
{ "netbios-name-servers", "IA", &dhcp_universe, 44 },
{ "netbios-dd-server", "IA", &dhcp_universe, 45 },
{ "netbios-node-type", "B", &dhcp_universe, 46 },
{ "netbios-scope", "t", &dhcp_universe, 47 },
{ "font-servers", "IA", &dhcp_universe, 48 },
{ "x-display-manager", "IA", &dhcp_universe, 49 },
{ "dhcp-requested-address", "I", &dhcp_universe, 50 },
{ "dhcp-lease-time", "L", &dhcp_universe, 51 },
{ "dhcp-option-overload", "B", &dhcp_universe, 52 },
{ "dhcp-message-type", "B", &dhcp_universe, 53 },
{ "dhcp-server-identifier", "I", &dhcp_universe, 54 },
{ "dhcp-parameter-request-list", "BA", &dhcp_universe, 55 },
{ "dhcp-message", "t", &dhcp_universe, 56 },
{ "dhcp-max-message-size", "S", &dhcp_universe, 57 },
{ "dhcp-renewal-time", "L", &dhcp_universe, 58 },
{ "dhcp-rebinding-time", "L", &dhcp_universe, 59 },
{ "dhcp-class-identifier", "t", &dhcp_universe, 60 },
{ "dhcp-client-identifier", "X", &dhcp_universe, 61 },
{ "option-62", "X", &dhcp_universe, 62 },
{ "option-63", "X", &dhcp_universe, 63 },
{ "option-64", "X", &dhcp_universe, 64 },
{ "option-65", "X", &dhcp_universe, 65 },
{ "option-66", "X", &dhcp_universe, 66 },
{ "option-67", "X", &dhcp_universe, 67 },
{ "option-68", "X", &dhcp_universe, 68 },
{ "option-69", "X", &dhcp_universe, 69 },
{ "option-70", "X", &dhcp_universe, 70 },
{ "option-71", "X", &dhcp_universe, 71 },
{ "option-72", "X", &dhcp_universe, 72 },
{ "option-73", "X", &dhcp_universe, 73 },
{ "option-74", "X", &dhcp_universe, 74 },
{ "option-75", "X", &dhcp_universe, 75 },
{ "option-76", "X", &dhcp_universe, 76 },
{ "dhcp-user-class-identifier", "t", &dhcp_universe, 77 },
{ "option-78", "X", &dhcp_universe, 78 },
{ "option-79", "X", &dhcp_universe, 79 },
{ "option-80", "X", &dhcp_universe, 80 },
{ "option-81", "X", &dhcp_universe, 81 },
{ "option-82", "X", &dhcp_universe, 82 },
{ "option-83", "X", &dhcp_universe, 83 },
{ "option-84", "X", &dhcp_universe, 84 },
{ "nds-servers", "IA", &dhcp_universe, 85 },
{ "nds-tree-name", "X", &dhcp_universe, 86 },
{ "nds-context", "X", &dhcp_universe, 87 },
{ "option-88", "X", &dhcp_universe, 88 },
{ "option-89", "X", &dhcp_universe, 89 },
{ "option-90", "X", &dhcp_universe, 90 },
{ "option-91", "X", &dhcp_universe, 91 },
{ "option-92", "X", &dhcp_universe, 92 },
{ "option-93", "X", &dhcp_universe, 93 },
{ "option-94", "X", &dhcp_universe, 94 },
{ "option-95", "X", &dhcp_universe, 95 },
{ "option-96", "X", &dhcp_universe, 96 },
{ "option-97", "X", &dhcp_universe, 97 },
{ "option-98", "X", &dhcp_universe, 98 },
{ "option-99", "X", &dhcp_universe, 99 },
{ "option-100", "X", &dhcp_universe, 100 },
{ "option-101", "X", &dhcp_universe, 101 },
{ "option-102", "X", &dhcp_universe, 102 },
{ "option-103", "X", &dhcp_universe, 103 },
{ "option-104", "X", &dhcp_universe, 104 },
{ "option-105", "X", &dhcp_universe, 105 },
{ "option-106", "X", &dhcp_universe, 106 },
{ "option-107", "X", &dhcp_universe, 107 },
{ "option-108", "X", &dhcp_universe, 108 },
{ "option-109", "X", &dhcp_universe, 109 },
{ "option-110", "X", &dhcp_universe, 110 },
{ "option-111", "X", &dhcp_universe, 111 },
{ "option-112", "X", &dhcp_universe, 112 },
{ "option-113", "X", &dhcp_universe, 113 },
{ "option-114", "X", &dhcp_universe, 114 },
{ "option-115", "X", &dhcp_universe, 115 },
{ "option-116", "X", &dhcp_universe, 116 },
{ "option-117", "X", &dhcp_universe, 117 },
{ "option-118", "X", &dhcp_universe, 118 },
{ "option-119", "X", &dhcp_universe, 119 },
{ "option-120", "X", &dhcp_universe, 120 },
{ "option-121", "X", &dhcp_universe, 121 },
{ "option-122", "X", &dhcp_universe, 122 },
{ "option-123", "X", &dhcp_universe, 123 },
{ "option-124", "X", &dhcp_universe, 124 },
{ "option-125", "X", &dhcp_universe, 125 },
{ "option-126", "X", &dhcp_universe, 126 },
{ "option-127", "X", &dhcp_universe, 127 },
{ "option-128", "X", &dhcp_universe, 128 },
{ "option-129", "X", &dhcp_universe, 129 },
{ "option-130", "X", &dhcp_universe, 130 },
{ "option-131", "X", &dhcp_universe, 131 },
{ "option-132", "X", &dhcp_universe, 132 },
{ "option-133", "X", &dhcp_universe, 133 },
{ "option-134", "X", &dhcp_universe, 134 },
{ "option-135", "X", &dhcp_universe, 135 },
{ "option-136", "X", &dhcp_universe, 136 },
{ "option-137", "X", &dhcp_universe, 137 },
{ "option-138", "X", &dhcp_universe, 138 },
{ "option-139", "X", &dhcp_universe, 139 },
{ "option-140", "X", &dhcp_universe, 140 },
{ "option-141", "X", &dhcp_universe, 141 },
{ "option-142", "X", &dhcp_universe, 142 },
{ "option-143", "X", &dhcp_universe, 143 },
{ "option-144", "X", &dhcp_universe, 144 },
{ "option-145", "X", &dhcp_universe, 145 },
{ "option-146", "X", &dhcp_universe, 146 },
{ "option-147", "X", &dhcp_universe, 147 },
{ "option-148", "X", &dhcp_universe, 148 },
{ "option-149", "X", &dhcp_universe, 149 },
{ "option-150", "X", &dhcp_universe, 150 },
{ "option-151", "X", &dhcp_universe, 151 },
{ "option-152", "X", &dhcp_universe, 152 },
{ "option-153", "X", &dhcp_universe, 153 },
{ "option-154", "X", &dhcp_universe, 154 },
{ "option-155", "X", &dhcp_universe, 155 },
{ "option-156", "X", &dhcp_universe, 156 },
{ "option-157", "X", &dhcp_universe, 157 },
{ "option-158", "X", &dhcp_universe, 158 },
{ "option-159", "X", &dhcp_universe, 159 },
{ "option-160", "X", &dhcp_universe, 160 },
{ "option-161", "X", &dhcp_universe, 161 },
{ "option-162", "X", &dhcp_universe, 162 },
{ "option-163", "X", &dhcp_universe, 163 },
{ "option-164", "X", &dhcp_universe, 164 },
{ "option-165", "X", &dhcp_universe, 165 },
{ "option-166", "X", &dhcp_universe, 166 },
{ "option-167", "X", &dhcp_universe, 167 },
{ "option-168", "X", &dhcp_universe, 168 },
{ "option-169", "X", &dhcp_universe, 169 },
{ "option-170", "X", &dhcp_universe, 170 },
{ "option-171", "X", &dhcp_universe, 171 },
{ "option-172", "X", &dhcp_universe, 172 },
{ "option-173", "X", &dhcp_universe, 173 },
{ "option-174", "X", &dhcp_universe, 174 },
{ "option-175", "X", &dhcp_universe, 175 },
{ "option-176", "X", &dhcp_universe, 176 },
{ "option-177", "X", &dhcp_universe, 177 },
{ "option-178", "X", &dhcp_universe, 178 },
{ "option-179", "X", &dhcp_universe, 179 },
{ "option-180", "X", &dhcp_universe, 180 },
{ "option-181", "X", &dhcp_universe, 181 },
{ "option-182", "X", &dhcp_universe, 182 },
{ "option-183", "X", &dhcp_universe, 183 },
{ "option-184", "X", &dhcp_universe, 184 },
{ "option-185", "X", &dhcp_universe, 185 },
{ "option-186", "X", &dhcp_universe, 186 },
{ "option-187", "X", &dhcp_universe, 187 },
{ "option-188", "X", &dhcp_universe, 188 },
{ "option-189", "X", &dhcp_universe, 189 },
{ "option-190", "X", &dhcp_universe, 190 },
{ "option-191", "X", &dhcp_universe, 191 },
{ "option-192", "X", &dhcp_universe, 192 },
{ "option-193", "X", &dhcp_universe, 193 },
{ "option-194", "X", &dhcp_universe, 194 },
{ "option-195", "X", &dhcp_universe, 195 },
{ "option-196", "X", &dhcp_universe, 196 },
{ "option-197", "X", &dhcp_universe, 197 },
{ "option-198", "X", &dhcp_universe, 198 },
{ "option-199", "X", &dhcp_universe, 199 },
{ "option-200", "X", &dhcp_universe, 200 },
{ "option-201", "X", &dhcp_universe, 201 },
{ "option-202", "X", &dhcp_universe, 202 },
{ "option-203", "X", &dhcp_universe, 203 },
{ "option-204", "X", &dhcp_universe, 204 },
{ "option-205", "X", &dhcp_universe, 205 },
{ "option-206", "X", &dhcp_universe, 206 },
{ "option-207", "X", &dhcp_universe, 207 },
{ "option-208", "X", &dhcp_universe, 208 },
{ "option-209", "X", &dhcp_universe, 209 },
{ "option-210", "X", &dhcp_universe, 210 },
{ "option-211", "X", &dhcp_universe, 211 },
{ "option-212", "X", &dhcp_universe, 212 },
{ "option-213", "X", &dhcp_universe, 213 },
{ "option-214", "X", &dhcp_universe, 214 },
{ "option-215", "X", &dhcp_universe, 215 },
{ "option-216", "X", &dhcp_universe, 216 },
{ "option-217", "X", &dhcp_universe, 217 },
{ "option-218", "X", &dhcp_universe, 218 },
{ "option-219", "X", &dhcp_universe, 219 },
{ "option-220", "X", &dhcp_universe, 220 },
{ "option-221", "X", &dhcp_universe, 221 },
{ "option-222", "X", &dhcp_universe, 222 },
{ "option-223", "X", &dhcp_universe, 223 },
{ "option-224", "X", &dhcp_universe, 224 },
{ "option-225", "X", &dhcp_universe, 225 },
{ "option-226", "X", &dhcp_universe, 226 },
{ "option-227", "X", &dhcp_universe, 227 },
{ "option-228", "X", &dhcp_universe, 228 },
{ "option-229", "X", &dhcp_universe, 229 },
{ "option-230", "X", &dhcp_universe, 230 },
{ "option-231", "X", &dhcp_universe, 231 },
{ "option-232", "X", &dhcp_universe, 232 },
{ "option-233", "X", &dhcp_universe, 233 },
{ "option-234", "X", &dhcp_universe, 234 },
{ "option-235", "X", &dhcp_universe, 235 },
{ "option-236", "X", &dhcp_universe, 236 },
{ "option-237", "X", &dhcp_universe, 237 },
{ "option-238", "X", &dhcp_universe, 238 },
{ "option-239", "X", &dhcp_universe, 239 },
{ "option-240", "X", &dhcp_universe, 240 },
{ "option-241", "X", &dhcp_universe, 241 },
{ "option-242", "X", &dhcp_universe, 242 },
{ "option-243", "X", &dhcp_universe, 243 },
{ "option-244", "X", &dhcp_universe, 244 },
{ "option-245", "X", &dhcp_universe, 245 },
{ "option-246", "X", &dhcp_universe, 246 },
{ "option-247", "X", &dhcp_universe, 247 },
{ "option-248", "X", &dhcp_universe, 248 },
{ "option-249", "X", &dhcp_universe, 249 },
{ "option-250", "X", &dhcp_universe, 250 },
{ "option-251", "X", &dhcp_universe, 251 },
{ "option-252", "X", &dhcp_universe, 252 },
{ "option-253", "X", &dhcp_universe, 253 },
{ "option-254", "X", &dhcp_universe, 254 },
{ "option-end", "e", &dhcp_universe, 255 },
};
/* Default dhcp option priority list (this is ad hoc and should not be
mistaken for a carefully crafted and optimized list). */
unsigned char dhcp_option_default_priority_list [] = {
DHO_DHCP_REQUESTED_ADDRESS,
DHO_DHCP_OPTION_OVERLOAD,
DHO_DHCP_MAX_MESSAGE_SIZE,
DHO_DHCP_RENEWAL_TIME,
DHO_DHCP_REBINDING_TIME,
DHO_DHCP_CLASS_IDENTIFIER,
DHO_DHCP_CLIENT_IDENTIFIER,
DHO_SUBNET_MASK,
DHO_TIME_OFFSET,
DHO_ROUTERS,
DHO_TIME_SERVERS,
DHO_NAME_SERVERS,
DHO_DOMAIN_NAME_SERVERS,
DHO_HOST_NAME,
DHO_LOG_SERVERS,
DHO_COOKIE_SERVERS,
DHO_LPR_SERVERS,
DHO_IMPRESS_SERVERS,
DHO_RESOURCE_LOCATION_SERVERS,
DHO_HOST_NAME,
DHO_BOOT_SIZE,
DHO_MERIT_DUMP,
DHO_DOMAIN_NAME,
DHO_SWAP_SERVER,
DHO_ROOT_PATH,
DHO_EXTENSIONS_PATH,
DHO_IP_FORWARDING,
DHO_NON_LOCAL_SOURCE_ROUTING,
DHO_POLICY_FILTER,
DHO_MAX_DGRAM_REASSEMBLY,
DHO_DEFAULT_IP_TTL,
DHO_PATH_MTU_AGING_TIMEOUT,
DHO_PATH_MTU_PLATEAU_TABLE,
DHO_INTERFACE_MTU,
DHO_ALL_SUBNETS_LOCAL,
DHO_BROADCAST_ADDRESS,
DHO_PERFORM_MASK_DISCOVERY,
DHO_MASK_SUPPLIER,
DHO_ROUTER_DISCOVERY,
DHO_ROUTER_SOLICITATION_ADDRESS,
DHO_STATIC_ROUTES,
DHO_TRAILER_ENCAPSULATION,
DHO_ARP_CACHE_TIMEOUT,
DHO_IEEE802_3_ENCAPSULATION,
DHO_DEFAULT_TCP_TTL,
DHO_TCP_KEEPALIVE_INTERVAL,
DHO_TCP_KEEPALIVE_GARBAGE,
DHO_NIS_DOMAIN,
DHO_NIS_SERVERS,
DHO_NTP_SERVERS,
DHO_VENDOR_ENCAPSULATED_OPTIONS,
DHO_NETBIOS_NAME_SERVERS,
DHO_NETBIOS_DD_SERVER,
DHO_NETBIOS_NODE_TYPE,
DHO_NETBIOS_SCOPE,
DHO_FONT_SERVERS,
DHO_X_DISPLAY_MANAGER,
DHO_DHCP_PARAMETER_REQUEST_LIST,
/* Presently-undefined options... */
62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178,
179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190,
191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202,
203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214,
215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
251, 252, 253, 254,
};
int sizeof_dhcp_option_default_priority_list =
sizeof dhcp_option_default_priority_list;
char *hardware_types [] = {
"unknown-0",
"ethernet",
"unknown-2",
"unknown-3",
"unknown-4",
"unknown-5",
"token-ring",
"unknown-7",
"unknown-8",
"unknown-9",
"unknown-10",
"unknown-11",
"unknown-12",
"unknown-13",
"unknown-14",
"unknown-15",
"unknown-16",
"unknown-17",
"unknown-18",
"unknown-19",
"unknown-20",
"unknown-21",
"unknown-22",
"unknown-23",
"unknown-24",
"unknown-25",
"unknown-26",
"unknown-27",
"unknown-28",
"unknown-29",
"unknown-30",
"unknown-31",
"unknown-32",
"unknown-33",
"unknown-34",
"unknown-35",
"unknown-36",
"unknown-37",
"unknown-38",
"unknown-39",
"unknown-40",
"unknown-41",
"unknown-42",
"unknown-43",
"unknown-44",
"unknown-45",
"unknown-46",
"unknown-47",
"unknown-48",
"unknown-49",
"unknown-50",
"unknown-51",
"unknown-52",
"unknown-53",
"unknown-54",
"unknown-55",
"unknown-56",
"unknown-57",
"unknown-58",
"unknown-59",
"unknown-60",
"unknown-61",
"unknown-62",
"unknown-63",
"unknown-64",
"unknown-65",
"unknown-66",
"unknown-67",
"unknown-68",
"unknown-69",
"unknown-70",
"unknown-71",
"unknown-72",
"unknown-73",
"unknown-74",
"unknown-75",
"unknown-76",
"unknown-77",
"unknown-78",
"unknown-79",
"unknown-80",
"unknown-81",
"unknown-82",
"unknown-83",
"unknown-84",
"unknown-85",
"unknown-86",
"unknown-87",
"unknown-88",
"unknown-89",
"unknown-90",
"unknown-91",
"unknown-92",
"unknown-93",
"unknown-94",
"unknown-95",
"unknown-96",
"unknown-97",
"unknown-98",
"unknown-99",
"unknown-100",
"unknown-101",
"unknown-102",
"unknown-103",
"unknown-104",
"unknown-105",
"unknown-106",
"unknown-107",
"unknown-108",
"unknown-109",
"unknown-110",
"unknown-111",
"unknown-112",
"unknown-113",
"unknown-114",
"unknown-115",
"unknown-116",
"unknown-117",
"unknown-118",
"unknown-119",
"unknown-120",
"unknown-121",
"unknown-122",
"unknown-123",
"unknown-124",
"unknown-125",
"unknown-126",
"unknown-127",
"unknown-128",
"unknown-129",
"unknown-130",
"unknown-131",
"unknown-132",
"unknown-133",
"unknown-134",
"unknown-135",
"unknown-136",
"unknown-137",
"unknown-138",
"unknown-139",
"unknown-140",
"unknown-141",
"unknown-142",
"unknown-143",
"unknown-144",
"unknown-145",
"unknown-146",
"unknown-147",
"unknown-148",
"unknown-149",
"unknown-150",
"unknown-151",
"unknown-152",
"unknown-153",
"unknown-154",
"unknown-155",
"unknown-156",
"unknown-157",
"unknown-158",
"unknown-159",
"unknown-160",
"unknown-161",
"unknown-162",
"unknown-163",
"unknown-164",
"unknown-165",
"unknown-166",
"unknown-167",
"unknown-168",
"unknown-169",
"unknown-170",
"unknown-171",
"unknown-172",
"unknown-173",
"unknown-174",
"unknown-175",
"unknown-176",
"unknown-177",
"unknown-178",
"unknown-179",
"unknown-180",
"unknown-181",
"unknown-182",
"unknown-183",
"unknown-184",
"unknown-185",
"unknown-186",
"unknown-187",
"unknown-188",
"unknown-189",
"unknown-190",
"unknown-191",
"unknown-192",
"unknown-193",
"unknown-194",
"unknown-195",
"unknown-196",
"unknown-197",
"unknown-198",
"unknown-199",
"unknown-200",
"unknown-201",
"unknown-202",
"unknown-203",
"unknown-204",
"unknown-205",
"unknown-206",
"unknown-207",
"unknown-208",
"unknown-209",
"unknown-210",
"unknown-211",
"unknown-212",
"unknown-213",
"unknown-214",
"unknown-215",
"unknown-216",
"unknown-217",
"unknown-218",
"unknown-219",
"unknown-220",
"unknown-221",
"unknown-222",
"unknown-223",
"unknown-224",
"unknown-225",
"unknown-226",
"unknown-227",
"unknown-228",
"unknown-229",
"unknown-230",
"unknown-231",
"unknown-232",
"unknown-233",
"unknown-234",
"unknown-235",
"unknown-236",
"unknown-237",
"unknown-238",
"unknown-239",
"unknown-240",
"unknown-241",
"unknown-242",
"unknown-243",
"unknown-244",
"unknown-245",
"unknown-246",
"unknown-247",
"unknown-248",
"unknown-249",
"unknown-250",
"unknown-251",
"unknown-252",
"unknown-253",
"unknown-254",
"unknown-255" };
struct hash_table universe_hash;
void initialize_universes()
{
int i;
dhcp_universe.name = "dhcp";
dhcp_universe.hash = new_hash ();
if (!dhcp_universe.hash)
error ("Can't allocate dhcp option hash table.");
for (i = 0; i < 256; i++) {
dhcp_universe.options [i] = &dhcp_options [i];
add_hash (dhcp_universe.hash,
(unsigned char *)dhcp_options [i].name, 0,
(unsigned char *)&dhcp_options [i]);
}
universe_hash.hash_count = DEFAULT_HASH_SIZE;
add_hash (&universe_hash,
(unsigned char *)dhcp_universe.name, 0,
(unsigned char *)&dhcp_universe);
}

View File

@ -0,0 +1,412 @@
/* tree.c
Routines for manipulating parse trees... */
/*
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: tree.c,v 1.10 1997/05/09 08:14:57 mellon Exp $ Copyright (c) 1995, 1996, 1997 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static TIME tree_evaluate_recurse PROTO ((int *, unsigned char **, int *,
struct tree *));
static TIME do_host_lookup PROTO ((int *, unsigned char **, int *,
struct dns_host_entry *));
static void do_data_copy PROTO ((int *, unsigned char **, int *,
unsigned char *, int));
pair cons (car, cdr)
caddr_t car;
pair cdr;
{
pair foo = (pair)dmalloc (sizeof *foo, "cons");
if (!foo)
error ("no memory for cons.");
foo -> car = car;
foo -> cdr = cdr;
return foo;
}
struct tree_cache *tree_cache (tree)
struct tree *tree;
{
struct tree_cache *tc;
tc = new_tree_cache ("tree_cache");
if (!tc)
return 0;
tc -> value = (unsigned char *)0;
tc -> len = tc -> buf_size = 0;
tc -> timeout = 0;
tc -> tree = tree;
return tc;
}
struct tree *tree_host_lookup (name)
char *name;
{
struct tree *nt;
nt = new_tree ("tree_host_lookup");
if (!nt)
error ("No memory for host lookup tree node.");
nt -> op = TREE_HOST_LOOKUP;
nt -> data.host_lookup.host = enter_dns_host (name);
return nt;
}
struct dns_host_entry *enter_dns_host (name)
char *name;
{
struct dns_host_entry *dh;
if (!(dh = (struct dns_host_entry *)dmalloc
(sizeof (struct dns_host_entry), "enter_dns_host"))
|| !(dh -> hostname = dmalloc (strlen (name) + 1,
"enter_dns_host")))
error ("Can't allocate space for new host.");
strcpy (dh -> hostname, name);
dh -> data = (unsigned char *)0;
dh -> data_len = 0;
dh -> buf_len = 0;
dh -> timeout = 0;
return dh;
}
struct tree *tree_const (data, len)
unsigned char *data;
int len;
{
struct tree *nt;
if (!(nt = new_tree ("tree_const"))
|| !(nt -> data.const_val.data =
(unsigned char *)dmalloc (len, "tree_const")))
error ("No memory for constant data tree node.");
nt -> op = TREE_CONST;
memcpy (nt -> data.const_val.data, data, len);
nt -> data.const_val.len = len;
return nt;
}
struct tree *tree_concat (left, right)
struct tree *left, *right;
{
struct tree *nt;
/* If we're concatenating a null tree to a non-null tree, just
return the non-null tree; if both trees are null, return
a null tree. */
if (!left)
return right;
if (!right)
return left;
/* If both trees are constant, combine them. */
if (left -> op == TREE_CONST && right -> op == TREE_CONST) {
unsigned char *buf = dmalloc (left -> data.const_val.len
+ right -> data.const_val.len,
"tree_concat");
if (!buf)
error ("No memory to concatenate constants.");
memcpy (buf, left -> data.const_val.data,
left -> data.const_val.len);
memcpy (buf + left -> data.const_val.len,
right -> data.const_val.data,
right -> data.const_val.len);
dfree (left -> data.const_val.data, "tree_concat");
dfree (right -> data.const_val.data, "tree_concat");
left -> data.const_val.data = buf;
left -> data.const_val.len += right -> data.const_val.len;
free_tree (right, "tree_concat");
return left;
}
/* Otherwise, allocate a new node to concatenate the two. */
if (!(nt = new_tree ("tree_concat")))
error ("No memory for data tree concatenation node.");
nt -> op = TREE_CONCAT;
nt -> data.concat.left = left;
nt -> data.concat.right = right;
return nt;
}
struct tree *tree_limit (tree, limit)
struct tree *tree;
int limit;
{
struct tree *rv;
/* If the tree we're limiting is constant, limit it now. */
if (tree -> op == TREE_CONST) {
if (tree -> data.const_val.len > limit)
tree -> data.const_val.len = limit;
return tree;
}
/* Otherwise, put in a node which enforces the limit on evaluation. */
rv = new_tree ("tree_limit");
if (!rv)
return (struct tree *)0;
rv -> op = TREE_LIMIT;
rv -> data.limit.tree = tree;
rv -> data.limit.limit = limit;
return rv;
}
int tree_evaluate (tree_cache)
struct tree_cache *tree_cache;
{
unsigned char *bp = tree_cache -> value;
int bc = tree_cache -> buf_size;
int bufix = 0;
/* If there's no tree associated with this cache, it evaluates
to a constant and that was detected at startup. */
if (!tree_cache -> tree)
return 1;
/* Try to evaluate the tree without allocating more memory... */
tree_cache -> timeout = tree_evaluate_recurse (&bufix, &bp, &bc,
tree_cache -> tree);
/* No additional allocation needed? */
if (bufix <= bc) {
tree_cache -> len = bufix;
return 1;
}
/* If we can't allocate more memory, return with what we
have (maybe nothing). */
if (!(bp = (unsigned char *)dmalloc (bufix, "tree_evaluate")))
return 0;
/* Record the change in conditions... */
bc = bufix;
bufix = 0;
/* Note that the size of the result shouldn't change on the
second call to tree_evaluate_recurse, since we haven't
changed the ``current'' time. */
tree_evaluate_recurse (&bufix, &bp, &bc, tree_cache -> tree);
/* Free the old buffer if needed, then store the new buffer
location and size and return. */
if (tree_cache -> value)
dfree (tree_cache -> value, "tree_evaluate");
tree_cache -> value = bp;
tree_cache -> len = bufix;
tree_cache -> buf_size = bc;
return 1;
}
static TIME tree_evaluate_recurse (bufix, bufp, bufcount, tree)
int *bufix;
unsigned char **bufp;
int *bufcount;
struct tree *tree;
{
int limit;
TIME t1, t2;
switch (tree -> op) {
case TREE_CONCAT:
t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
tree -> data.concat.left);
t2 = tree_evaluate_recurse (bufix, bufp, bufcount,
tree -> data.concat.right);
if (t1 > t2)
return t2;
return t1;
case TREE_HOST_LOOKUP:
return do_host_lookup (bufix, bufp, bufcount,
tree -> data.host_lookup.host);
case TREE_CONST:
do_data_copy (bufix, bufp, bufcount,
tree -> data.const_val.data,
tree -> data.const_val.len);
t1 = MAX_TIME;
return t1;
case TREE_LIMIT:
limit = *bufix + tree -> data.limit.limit;
t1 = tree_evaluate_recurse (bufix, bufp, bufcount,
tree -> data.limit.tree);
*bufix = limit;
return t1;
default:
warn ("Bad node id in tree: %d.");
t1 = MAX_TIME;
return t1;
}
}
static TIME do_host_lookup (bufix, bufp, bufcount, dns)
int *bufix;
unsigned char **bufp;
int *bufcount;
struct dns_host_entry *dns;
{
struct hostent *h;
int i;
int new_len;
#ifdef DEBUG_EVAL
debug ("time: now = %d dns = %d %d diff = %d",
cur_time, dns -> timeout, cur_time - dns -> timeout);
#endif
/* If the record hasn't timed out, just copy the data and return. */
if (cur_time <= dns -> timeout) {
#ifdef DEBUG_EVAL
debug ("easy copy: %x %d %x",
dns -> data, dns -> data_len,
dns -> data ? *(int *)(dns -> data) : 0);
#endif
do_data_copy (bufix, bufp, bufcount,
dns -> data, dns -> data_len);
return dns -> timeout;
}
#ifdef DEBUG_EVAL
debug ("Looking up %s", dns -> hostname);
#endif
/* Otherwise, look it up... */
h = gethostbyname (dns -> hostname);
if (!h) {
#ifndef NO_H_ERRNO
switch (h_errno) {
case HOST_NOT_FOUND:
#endif
warn ("%s: host unknown.", dns -> hostname);
#ifndef NO_H_ERRNO
break;
case TRY_AGAIN:
warn ("%s: temporary name server failure",
dns -> hostname);
break;
case NO_RECOVERY:
warn ("%s: name server failed", dns -> hostname);
break;
case NO_DATA:
warn ("%s: no A record associated with address",
dns -> hostname);
}
#endif /* !NO_H_ERRNO */
/* Okay to try again after a minute. */
return cur_time + 60;
}
#ifdef DEBUG_EVAL
debug ("Lookup succeeded; first address is %x",
h -> h_addr_list [0]);
#endif
/* Count the number of addresses we got... */
for (i = 0; h -> h_addr_list [i]; i++)
;
/* Do we need to allocate more memory? */
new_len = i * h -> h_length;
if (dns -> buf_len < i) {
unsigned char *buf =
(unsigned char *)dmalloc (new_len, "do_host_lookup");
/* If we didn't get more memory, use what we have. */
if (!buf) {
new_len = dns -> buf_len;
if (!dns -> buf_len) {
dns -> timeout = cur_time + 60;
return dns -> timeout;
}
} else {
if (dns -> data)
dfree (dns -> data, "do_host_lookup");
dns -> data = buf;
dns -> buf_len = new_len;
}
}
/* Addresses are conveniently stored one to the buffer, so we
have to copy them out one at a time... :'( */
for (i = 0; i < new_len / h -> h_length; i++) {
memcpy (dns -> data + h -> h_length * i,
h -> h_addr_list [i], h -> h_length);
}
#ifdef DEBUG_EVAL
debug ("dns -> data: %x h -> h_addr_list [0]: %x",
*(int *)(dns -> data), h -> h_addr_list [0]);
#endif
dns -> data_len = new_len;
/* Set the timeout for an hour from now.
XXX This should really use the time on the DNS reply. */
dns -> timeout = cur_time + 3600;
#ifdef DEBUG_EVAL
debug ("hard copy: %x %d %x",
dns -> data, dns -> data_len, *(int *)(dns -> data));
#endif
do_data_copy (bufix, bufp, bufcount, dns -> data, dns -> data_len);
return dns -> timeout;
}
static void do_data_copy (bufix, bufp, bufcount, data, len)
int *bufix;
unsigned char **bufp;
int *bufcount;
unsigned char *data;
int len;
{
int space = *bufcount - *bufix;
/* If there's more space than we need, use only what we need. */
if (space > len)
space = len;
/* Copy as much data as will fit, then increment the buffer index
by the amount we actually had to copy, which could be more. */
if (space > 0)
memcpy (*bufp + *bufix, data, space);
*bufix += len;
}

View File

@ -0,0 +1,298 @@
/* upf.c
Ultrix PacketFilter interface code.
/*
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: upf.c,v 1.3 1997/10/20 21:47:15 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#if defined (USE_UPF_SEND) || defined (USE_UPF_RECEIVE)
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <net/pfilt.h>
#include <netinet/in_systm.h>
#include "includes/netinet/ip.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
/* Reinitializes the specified interface after an address change. This
is not required for packet-filter APIs. */
#ifdef USE_UPF_SEND
void if_reinitialize_send (info)
struct interface_info *info;
{
}
#endif
#ifdef USE_UPF_RECEIVE
void if_reinitialize_receive (info)
struct interface_info *info;
{
}
#endif
/* Called by get_interface_list for each interface that's discovered.
Opens a packet filter for each interface and adds it to the select
mask. */
int if_register_upf (info)
struct interface_info *info;
{
int sock;
char filename[50];
int b;
struct endevp param;
/* Open a UPF device */
for (b = 0; 1; b++) {
#ifndef NO_SNPRINTF
snprintf(filename, sizeof(filename), "/dev/pf/pfilt%d", b);
#else
sprintf(filename, "/dev/pf/pfilt%d", b);
#endif
sock = open (filename, O_RDWR, 0);
if (sock < 0) {
if (errno == EBUSY) {
continue;
} else {
error ("Can't find free upf: %m");
}
} else {
break;
}
}
/* Set the UPF device to point at this interface. */
if (ioctl (sock, EIOCSETIF, info -> ifp) < 0)
error ("Can't attach interface %s to upf device %s: %m",
info -> name, filename);
/* Get the hardware address. */
if (ioctl (sock, EIOCDEVP, &param) < 0)
error ("Can't get interface %s hardware address: %m",
info -> name);
/* We only know how to do ethernet. */
if (param.end_dev_type != ENDT_10MB)
error ("Invalid device type on network interface %s: %d",
info -> name, param.end_dev_type);
if (param.end_addr_len != 6)
error ("Invalid hardware address length on %s: %d",
info -> name, param.end_addr_len);
info -> hw_address.hlen = 6;
info -> hw_address.htype = ARPHRD_ETHER;
memcpy (&info -> hw_address.haddr [0], param.end_addr, 6);
return sock;
}
#endif /* USE_UPF_SEND || USE_UPF_RECEIVE */
#ifdef USE_UPF_SEND
void if_register_send (info)
struct interface_info *info;
{
/* If we're using the upf API for sending and receiving,
we don't need to register this interface twice. */
#ifndef USE_UPF_RECEIVE
info -> wfdesc = if_register_upf (info, interface);
#else
info -> wfdesc = info -> rfdesc;
#endif
if (!quiet_interface_discovery)
note ("Sending on UPF/%s/%s/%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_UPF_SEND */
#ifdef USE_UPF_RECEIVE
/* Packet filter program...
XXX Changes to the filter program may require changes to the constant
offsets used in if_register_send to patch the UPF program! XXX */
void if_register_receive (info)
struct interface_info *info;
{
int flag = 1;
u_int32_t addr;
struct enfilter pf;
u_int32_t bits;
/* Open a UPF device and hang it on this interface... */
info -> rfdesc = if_register_upf (info);
/* Allow the copyall flag to be set... */
if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
error ("Can't set ALLOWCOPYALL: %m");
/* Clear all the packet filter mode bits first... */
flag = (ENHOLDSIG | ENBATCH | ENTSTAMP | ENPROMISC |
ENNONEXCL | ENCOPYALL);
if (ioctl (info -> rfdesc, EIOCMBIC, &flag) < 0)
error ("Can't clear pfilt bits: %m");
/* Set the ENBATCH and ENCOPYALL bits... */
bits = ENBATCH | ENCOPYALL;
if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
error ("Can't set ENBATCH|ENCOPYALL: %m");
/* Set up the UPF filter program. */
/* XXX Unlike the BPF filter program, this one won't work if the
XXX IP packet is fragmented or if there are options on the IP
XXX header. */
pf.enf_Priority = 0;
pf.enf_FilterLen = 0;
pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 6;
pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
pf.enf_Filter [pf.enf_FilterLen++] = htons (ETHERTYPE_IP);
pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT;
pf.enf_Filter [pf.enf_FilterLen++] = htons (IPPROTO_UDP);
pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 11;
pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
pf.enf_Filter [pf.enf_FilterLen++] = htons (0xFF);
pf.enf_Filter [pf.enf_FilterLen++] = ENF_CAND;
pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 18;
pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
pf.enf_Filter [pf.enf_FilterLen++] = local_port;
if (ioctl (info -> rfdesc, EIOCSETF, &pf) < 0)
error ("Can't install packet filter program: %m");
if (!quiet_interface_discovery)
note ("Listening on UPF/%s/%s/%s",
info -> name,
print_hw_addr (info -> hw_address.htype,
info -> hw_address.hlen,
info -> hw_address.haddr),
(info -> shared_network ?
info -> shared_network -> name : "unattached"));
}
#endif /* USE_UPF_RECEIVE */
#ifdef USE_UPF_SEND
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
struct dhcp_packet *raw;
size_t len;
struct in_addr from;
struct sockaddr_in *to;
struct hardware *hto;
{
int bufp = 0;
unsigned char buf [256];
struct iovec iov [2];
/* Assemble the headers... */
assemble_hw_header (interface, buf, &bufp, hto);
assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
to -> sin_addr.s_addr, to -> sin_port,
(unsigned char *)raw, len);
/* Fire it off */
iov [0].iov_base = (char *)buf;
iov [0].iov_len = bufp;
iov [1].iov_base = (char *)raw;
iov [1].iov_len = len;
return writev(interface -> wfdesc, iov, 2);
}
#endif /* USE_UPF_SEND */
#ifdef USE_UPF_RECEIVE
ssize_t receive_packet (interface, buf, len, from, hfrom)
struct interface_info *interface;
unsigned char *buf;
size_t len;
struct sockaddr_in *from;
struct hardware *hfrom;
{
int nread;
int length = 0;
int offset = 0;
unsigned char ibuf [1500 + sizeof (struct enstamp)];
int bufix = 0;
length = read (interface -> rfdesc, ibuf, sizeof ibuf);
if (length <= 0)
return length;
bufix = sizeof (struct enstamp);
/* Decode the physical header... */
offset = decode_hw_header (interface, ibuf, bufix, hfrom);
/* If a physical layer checksum failed (dunno of any
physical layer that supports this, but WTH), skip this
packet. */
if (offset < 0) {
return 0;
}
bufix += offset;
length -= offset;
/* Decode the IP and UDP headers... */
offset = decode_udp_ip_header (interface, ibuf, bufix,
from, (unsigned char *)0, length);
/* If the IP or UDP checksum was bad, skip the packet... */
if (offset < 0)
return 0;
bufix += offset;
length -= offset;
/* Copy out the data in the packet... */
memcpy (buf, &ibuf [bufix], length);
return length;
}
#endif

View File

@ -0,0 +1,237 @@
/*
* ++Copyright++ 1983, 1989, 1993
* -
* Copyright (c) 1983, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* -
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies, and that
* the name of Digital Equipment Corporation not be used in advertising or
* publicity pertaining to distribution of the document or software without
* specific, written prior permission.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
* -
* --Copyright--
*/
/*
* @(#)nameser.h 8.1 (Berkeley) 6/2/93
* $Id: nameser.h,v 8.3 1995/08/21 01:27:12 vixie Exp
*/
#ifndef _NAMESER_H_
#define _NAMESER_H_
/*
* Define constants based on rfc883
*/
#define PACKETSZ 512 /* maximum packet size */
#define MAXDNAME 256 /* maximum domain name */
#define MAXCDNAME 255 /* maximum compressed domain name */
#define MAXLABEL 63 /* maximum length of domain label */
#define HFIXEDSZ 12 /* #/bytes of fixed data in header */
#define QFIXEDSZ 4 /* #/bytes of fixed data in query */
#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
#define INT32SZ 4 /* for systems without 32-bit ints */
#define INT16SZ 2 /* for systems without 16-bit ints */
#define INADDRSZ 4 /* for sizeof(struct inaddr) != 4 */
/*
* Internet nameserver port number
*/
#define NAMESERVER_PORT 53
/*
* Currently defined opcodes
*/
#define QUERY 0x0 /* standard query */
#define IQUERY 0x1 /* inverse query */
#define STATUS 0x2 /* nameserver status query */
/*#define xxx 0x3*/ /* 0x3 reserved */
#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */
#ifdef ALLOW_UPDATES
/* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
# define UPDATEA 0x9 /* add resource record */
# define UPDATED 0xa /* delete a specific resource record */
# define UPDATEDA 0xb /* delete all named resource record */
# define UPDATEM 0xc /* modify a specific resource record */
# define UPDATEMA 0xd /* modify all named resource record */
# define ZONEINIT 0xe /* initial zone transfer */
# define ZONEREF 0xf /* incremental zone referesh */
#endif
/*
* Currently defined response codes
*/
#define NOERROR 0 /* no error */
#define FORMERR 1 /* format error */
#define SERVFAIL 2 /* server failure */
#define NXDOMAIN 3 /* non existent domain */
#define NOTIMP 4 /* not implemented */
#define REFUSED 5 /* query refused */
#ifdef ALLOW_UPDATES
/* non standard */
# define NOCHANGE 0xf /* update failed to change db */
#endif
/*
* Type values for resources and queries
*/
#define T_A 1 /* host address */
#define T_NS 2 /* authoritative server */
#define T_MD 3 /* mail destination */
#define T_MF 4 /* mail forwarder */
#define T_CNAME 5 /* canonical name */
#define T_SOA 6 /* start of authority zone */
#define T_MB 7 /* mailbox domain name */
#define T_MG 8 /* mail group member */
#define T_MR 9 /* mail rename name */
#define T_NULL 10 /* null resource record */
#define T_WKS 11 /* well known service */
#define T_PTR 12 /* domain name pointer */
#define T_HINFO 13 /* host information */
#define T_MINFO 14 /* mailbox information */
#define T_MX 15 /* mail routing information */
#define T_TXT 16 /* text strings */
#define T_RP 17 /* responsible person */
#define T_AFSDB 18 /* AFS cell database */
#define T_X25 19 /* X_25 calling address */
#define T_ISDN 20 /* ISDN calling address */
#define T_RT 21 /* router */
#define T_NSAP 22 /* NSAP address */
#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */
#define T_SIG 24 /* security signature */
#define T_KEY 25 /* security key */
#define T_PX 26 /* X.400 mail mapping */
#define T_GPOS 27 /* geographical position (withdrawn) */
#define T_AAAA 28 /* IP6 Address */
#define T_LOC 29 /* Location Information */
/* non standard */
#define T_UINFO 100 /* user (finger) information */
#define T_UID 101 /* user ID */
#define T_GID 102 /* group ID */
#define T_UNSPEC 103 /* Unspecified format (binary data) */
/* Query type values which do not appear in resource records */
#define T_AXFR 252 /* transfer zone of authority */
#define T_MAILB 253 /* transfer mailbox records */
#define T_MAILA 254 /* transfer mail agent records */
#define T_ANY 255 /* wildcard match */
/*
* Values for class field
*/
#define C_IN 1 /* the arpa internet */
#define C_CHAOS 3 /* for chaos net (MIT) */
#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */
/* Query class values which do not appear in resource records */
#define C_ANY 255 /* wildcard match */
/*
* Status return codes for T_UNSPEC conversion routines
*/
#define CONV_SUCCESS 0
#define CONV_OVERFLOW (-1)
#define CONV_BADFMT (-2)
#define CONV_BADCKSUM (-3)
#define CONV_BADBUFLEN (-4)
/*
* Structure for query header. The order of the fields is machine- and
* compiler-dependent, depending on the byte/bit order and the layout
* of bit fields. We use bit fields only in int variables, as this
* is all ANSI requires. This requires a somewhat confusing rearrangement.
*/
typedef struct {
unsigned id :16; /* query identification number */
#if BYTE_ORDER == BIG_ENDIAN
/* fields in third byte */
unsigned qr: 1; /* response flag */
unsigned opcode: 4; /* purpose of message */
unsigned aa: 1; /* authoritive answer */
unsigned tc: 1; /* truncated message */
unsigned rd: 1; /* recursion desired */
/* fields in fourth byte */
unsigned ra: 1; /* recursion available */
unsigned pr:1; /* primary server required (non standard) */
unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */
unsigned rcode :4; /* response code */
#endif
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
/* fields in third byte */
unsigned rd :1; /* recursion desired */
unsigned tc :1; /* truncated message */
unsigned aa :1; /* authoritive answer */
unsigned opcode :4; /* purpose of message */
unsigned qr :1; /* response flag */
/* fields in fourth byte */
unsigned rcode :4; /* response code */
unsigned unused :2; /* unused bits (MBZ as of 4.9.3a3) */
unsigned pr:1; /* primary server required (non standard) */
unsigned ra :1; /* recursion available */
#endif
/* remaining bytes */
unsigned qdcount :16; /* number of question entries */
unsigned ancount :16; /* number of answer entries */
unsigned nscount :16; /* number of authority entries */
unsigned arcount :16; /* number of resource entries */
} HEADER;
/*
* Defines for handling compressed domain names
*/
#define INDIR_MASK 0xc0
/*
* Structure for passing resource records around.
*/
struct rrec {
int16_t r_zone; /* zone number */
int16_t r_class; /* class number */
int16_t r_type; /* type number */
u_int32_t r_ttl; /* time to live */
int r_size; /* size of data area */
char *r_data; /* pointer to data */
};
#endif /* !_NAMESER_H_ */

View File

@ -0,0 +1,57 @@
/* cdefs.h
Standard C definitions... */
/*
* Copyright (c) 1996 The Internet Software Consortium.
* All Rights Reserved.
* Copyright (c) 1995 RadioMail Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of RadioMail Corporation, the Internet Software
* Consortium nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY RADIOMAIL CORPORATION, THE INTERNET
* SOFTWARE CONSORTIUM AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL RADIOMAIL CORPORATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software was written for RadioMail Corporation by Ted Lemon
* under a contract with Vixie Enterprises. Further modifications have
* been made for the Internet Software Consortium under a contract
* with Vixie Laboratories.
*/
#if (defined (__GNUC__) || defined (__STDC__)) && !defined (BROKEN_ANSI)
#define PROTO(x) x
#define KandR(x)
#define ANSI_DECL(x) x
#if defined (__GNUC__)
#define INLINE inline
#else
#define INLINE
#endif /* __GNUC__ */
#else
#define PROTO(x) ()
#define KandR(x) x
#define ANSI_DECL(x)
#define INLINE
#endif /* __GNUC__ || __STDC__ */

View File

@ -0,0 +1,89 @@
/* freebsd.h
System dependencies for FreeBSD... */
/*
* Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software was written for the Internet Software Consortium by Ted Lemon
* under a contract with Vixie Laboratories.
*/
#define _ANSI_SOURCE
#include <syslog.h>
#include <sys/types.h>
#include <string.h>
#include <paths.h>
#include <errno.h>
#include <unistd.h>
#include <setjmp.h>
#include <limits.h>
#include <sys/wait.h>
#include <signal.h>
extern int h_errno;
#include <net/if.h>
#include <net/if_dl.h>
#define INADDR_LOOPBACK ((u_int32_t)0x7f000001)
/* Varargs stuff... */
#include <stdarg.h>
#define VA_DOTDOTDOT ...
#define va_dcl
#define VA_start(list, last) va_start (list, last)
#ifndef _PATH_DHCPD_PID
#define _PATH_DHCPD_PID "/var/run/dhcpd.pid"
#endif
#ifndef _PATH_DHCPD_DB
#define _PATH_DHCPD_DB "/var/db/dhcpd.leases"
#endif
#ifndef _PATH_DHCLIENT_PID
#define _PATH_DHCLIENT_PID "/var/run/dhclient.pid"
#endif
#ifndef _PATH_DHCLIENT_DB
#define _PATH_DHCLIENT_DB "/var/db/dhclient.leases"
#endif
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#include <sys/time.h>
#define TIME time_t
#define GET_TIME(x) time ((x))
#define HAVE_SA_LEN
#if defined (USE_DEFAULT_NETWORK)
# define USE_BPF
#endif

View File

@ -0,0 +1,167 @@
/* dhcp.h
Protocol structures... */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#define DHCP_UDP_OVERHEAD (14 + /* Ethernet header */ \
20 + /* IP header */ \
8) /* UDP header */
#define DHCP_SNAME_LEN 64
#define DHCP_FILE_LEN 128
#define DHCP_FIXED_NON_UDP 236
#define DHCP_FIXED_LEN (DHCP_FIXED_NON_UDP + DHCP_UDP_OVERHEAD)
/* Everything but options. */
#define DHCP_MTU_MAX 1500
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
#define BOOTP_MIN_LEN 300
#define DHCP_MIN_LEN 548
struct dhcp_packet {
u_int8_t op; /* Message opcode/type */
u_int8_t htype; /* Hardware addr type (see net/if_types.h) */
u_int8_t hlen; /* Hardware addr length */
u_int8_t hops; /* Number of relay agent hops from client */
u_int32_t xid; /* Transaction ID */
u_int16_t secs; /* Seconds since client started looking */
u_int16_t flags; /* Flag bits */
struct in_addr ciaddr; /* Client IP address (if already in use) */
struct in_addr yiaddr; /* Client IP address */
struct in_addr siaddr; /* IP address of next server to talk to */
struct in_addr giaddr; /* DHCP relay agent IP address */
unsigned char chaddr [16]; /* Client hardware address */
char sname [DHCP_SNAME_LEN]; /* Server name */
char file [DHCP_FILE_LEN]; /* Boot filename */
unsigned char options [DHCP_OPTION_LEN];
/* Optional parameters
(actual length dependent on MTU). */
};
/* BOOTP (rfc951) message types */
#define BOOTREQUEST 1
#define BOOTREPLY 2
/* Possible values for flags field... */
#define BOOTP_BROADCAST 32768L
/* Possible values for hardware type (htype) field... */
#define HTYPE_ETHER 1 /* Ethernet 10Mbps */
#define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
/* Magic cookie validating dhcp options field (and bootp vendor
extensions field). */
#define DHCP_OPTIONS_COOKIE "\143\202\123\143"
/* DHCP Option codes: */
#define DHO_PAD 0
#define DHO_SUBNET_MASK 1
#define DHO_TIME_OFFSET 2
#define DHO_ROUTERS 3
#define DHO_TIME_SERVERS 4
#define DHO_NAME_SERVERS 5
#define DHO_DOMAIN_NAME_SERVERS 6
#define DHO_LOG_SERVERS 7
#define DHO_COOKIE_SERVERS 8
#define DHO_LPR_SERVERS 9
#define DHO_IMPRESS_SERVERS 10
#define DHO_RESOURCE_LOCATION_SERVERS 11
#define DHO_HOST_NAME 12
#define DHO_BOOT_SIZE 13
#define DHO_MERIT_DUMP 14
#define DHO_DOMAIN_NAME 15
#define DHO_SWAP_SERVER 16
#define DHO_ROOT_PATH 17
#define DHO_EXTENSIONS_PATH 18
#define DHO_IP_FORWARDING 19
#define DHO_NON_LOCAL_SOURCE_ROUTING 20
#define DHO_POLICY_FILTER 21
#define DHO_MAX_DGRAM_REASSEMBLY 22
#define DHO_DEFAULT_IP_TTL 23
#define DHO_PATH_MTU_AGING_TIMEOUT 24
#define DHO_PATH_MTU_PLATEAU_TABLE 25
#define DHO_INTERFACE_MTU 26
#define DHO_ALL_SUBNETS_LOCAL 27
#define DHO_BROADCAST_ADDRESS 28
#define DHO_PERFORM_MASK_DISCOVERY 29
#define DHO_MASK_SUPPLIER 30
#define DHO_ROUTER_DISCOVERY 31
#define DHO_ROUTER_SOLICITATION_ADDRESS 32
#define DHO_STATIC_ROUTES 33
#define DHO_TRAILER_ENCAPSULATION 34
#define DHO_ARP_CACHE_TIMEOUT 35
#define DHO_IEEE802_3_ENCAPSULATION 36
#define DHO_DEFAULT_TCP_TTL 37
#define DHO_TCP_KEEPALIVE_INTERVAL 38
#define DHO_TCP_KEEPALIVE_GARBAGE 39
#define DHO_NIS_DOMAIN 40
#define DHO_NIS_SERVERS 41
#define DHO_NTP_SERVERS 42
#define DHO_VENDOR_ENCAPSULATED_OPTIONS 43
#define DHO_NETBIOS_NAME_SERVERS 44
#define DHO_NETBIOS_DD_SERVER 45
#define DHO_NETBIOS_NODE_TYPE 46
#define DHO_NETBIOS_SCOPE 47
#define DHO_FONT_SERVERS 48
#define DHO_X_DISPLAY_MANAGER 49
#define DHO_DHCP_REQUESTED_ADDRESS 50
#define DHO_DHCP_LEASE_TIME 51
#define DHO_DHCP_OPTION_OVERLOAD 52
#define DHO_DHCP_MESSAGE_TYPE 53
#define DHO_DHCP_SERVER_IDENTIFIER 54
#define DHO_DHCP_PARAMETER_REQUEST_LIST 55
#define DHO_DHCP_MESSAGE 56
#define DHO_DHCP_MAX_MESSAGE_SIZE 57
#define DHO_DHCP_RENEWAL_TIME 58
#define DHO_DHCP_REBINDING_TIME 59
#define DHO_DHCP_CLASS_IDENTIFIER 60
#define DHO_DHCP_CLIENT_IDENTIFIER 61
#define DHO_DHCP_USER_CLASS_ID 77
#define DHO_END 255
/* DHCP message types. */
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCPINFORM 8

View File

@ -0,0 +1,947 @@
/* dhcpd.h
Definitions for dhcpd... */
/*
* Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef __CYGWIN32__
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netdb.h>
#else
#define fd_set cygwin_fd_set
#include <sys/types.h>
#endif
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <ctype.h>
#include <time.h>
#include "cdefs.h"
#include "osdep.h"
#include "dhcp.h"
#include "tree.h"
#include "hash.h"
#include "inet.h"
#include "sysconf.h"
struct option_data {
int len;
u_int8_t *data;
};
struct string_list {
struct string_list *next;
char string [1];
};
/* A name server, from /etc/resolv.conf. */
struct name_server {
struct name_server *next;
struct sockaddr_in addr;
TIME rcdate;
};
/* A domain search list element. */
struct domain_search_list {
struct domain_search_list *next;
char *domain;
TIME rcdate;
};
/* A dhcp packet and the pointers to its option values. */
struct packet {
struct dhcp_packet *raw;
int packet_length;
int packet_type;
int options_valid;
int client_port;
struct iaddr client_addr;
struct interface_info *interface; /* Interface on which packet
was received. */
struct hardware *haddr; /* Physical link address
of local sender (maybe gateway). */
struct shared_network *shared_network;
struct option_data options [256];
};
struct hardware {
u_int8_t htype;
u_int8_t hlen;
u_int8_t haddr [16];
};
/* A dhcp lease declaration structure. */
struct lease {
struct lease *next;
struct lease *prev;
struct lease *n_uid, *n_hw;
struct lease *waitq_next;
struct iaddr ip_addr;
TIME starts, ends, timestamp;
unsigned char *uid;
int uid_len;
int uid_max;
unsigned char uid_buf [32];
char *hostname;
char *client_hostname;
struct host_decl *host;
struct subnet *subnet;
struct shared_network *shared_network;
struct hardware hardware_addr;
int flags;
# define STATIC_LEASE 1
# define BOOTP_LEASE 2
# define DYNAMIC_BOOTP_OK 4
# define PERSISTENT_FLAGS (DYNAMIC_BOOTP_OK)
# define EPHEMERAL_FLAGS (BOOTP_LEASE)
# define MS_NULL_TERMINATION 8
# define ABANDONED_LEASE 16
struct lease_state *state;
};
struct lease_state {
struct lease_state *next;
struct interface_info *ip;
TIME offered_expiry;
struct tree_cache *options [256];
u_int32_t expiry, renewal, rebind;
char *filename, *server_name;
u_int32_t xid;
u_int16_t secs;
u_int16_t bootp_flags;
struct in_addr ciaddr;
struct in_addr giaddr;
u_int8_t hops;
u_int8_t offer;
};
#define ROOT_GROUP 0
#define HOST_DECL 1
#define SHARED_NET_DECL 2
#define SUBNET_DECL 3
#define CLASS_DECL 4
#define GROUP_DECL 5
/* Possible modes in which discover_interfaces can run. */
#define DISCOVER_RUNNING 0
#define DISCOVER_SERVER 1
#define DISCOVER_UNCONFIGURED 2
#define DISCOVER_RELAY 3
#define DISCOVER_REQUESTED 4
/* Group of declarations that share common parameters. */
struct group {
struct group *next;
struct subnet *subnet;
struct shared_network *shared_network;
TIME default_lease_time;
TIME max_lease_time;
TIME bootp_lease_cutoff;
TIME bootp_lease_length;
char *filename;
char *server_name;
struct iaddr next_server;
int boot_unknown_clients;
int dynamic_bootp;
int allow_bootp;
int allow_booting;
int one_lease_per_client;
int get_lease_hostnames;
int use_host_decl_names;
struct tree_cache *options [256];
};
/* A dhcp host declaration structure. */
struct host_decl {
struct host_decl *n_ipaddr;
char *name;
struct hardware interface;
struct tree_cache *fixed_addr;
struct group *group;
};
struct shared_network {
struct shared_network *next;
char *name;
struct subnet *subnets;
struct interface_info *interface;
struct lease *leases;
struct lease *insertion_point;
struct lease *last_lease;
struct group *group;
};
struct subnet {
struct subnet *next_subnet;
struct subnet *next_sibling;
struct shared_network *shared_network;
struct interface_info *interface;
struct iaddr interface_address;
struct iaddr net;
struct iaddr netmask;
struct group *group;
};
struct class {
char *name;
struct group *group;
};
/* DHCP client lease structure... */
struct client_lease {
struct client_lease *next; /* Next lease in list. */
TIME expiry, renewal, rebind; /* Lease timeouts. */
struct iaddr address; /* Address being leased. */
char *server_name; /* Name of boot server. */
char *filename; /* Name of file we're supposed to boot. */
struct string_list *medium; /* Network medium. */
unsigned int is_static : 1; /* If set, lease is from config file. */
unsigned int is_bootp: 1; /* If set, lease was aquired with BOOTP. */
struct option_data options [256]; /* Options supplied with lease. */
};
/* Possible states in which the client can be. */
enum dhcp_state {
S_REBOOTING,
S_INIT,
S_SELECTING,
S_REQUESTING,
S_BOUND,
S_RENEWING,
S_REBINDING
};
/* Configuration information from the config file... */
struct client_config {
struct option_data defaults [256]; /* Default values for options. */
enum {
ACTION_DEFAULT, /* Use server value if present,
otherwise default. */
ACTION_SUPERSEDE, /* Always use default. */
ACTION_PREPEND, /* Prepend default to server. */
ACTION_APPEND, /* Append default to server. */
} default_actions [256];
struct option_data send_options [256]; /* Send these to server. */
u_int8_t required_options [256]; /* Options server must supply. */
u_int8_t requested_options [256]; /* Options to request from server. */
int requested_option_count; /* Number of requested options. */
TIME timeout; /* Start to panic if we don't get a
lease in this time period when
SELECTING. */
TIME initial_interval; /* All exponential backoff intervals
start here. */
TIME retry_interval; /* If the protocol failed to produce
an address before the timeout,
try the protocol again after this
many seconds. */
TIME select_interval; /* Wait this many seconds from the
first DHCPDISCOVER before
picking an offered lease. */
TIME reboot_timeout; /* When in INIT-REBOOT, wait this
long before giving up and going
to INIT. */
TIME backoff_cutoff; /* When doing exponential backoff,
never back off to an interval
longer than this amount. */
struct string_list *media; /* Possible network media values. */
char *script_name; /* Name of config script. */
enum { IGNORE, ACCEPT, PREFER } bootp_policy;
/* Ignore, accept or prefer BOOTP
responses. */
struct string_list *medium; /* Current network medium. */
struct iaddrlist *reject_list; /* Servers to reject. */
};
/* Per-interface state used in the dhcp client... */
struct client_state {
struct client_lease *active; /* Currently active lease. */
struct client_lease *new; /* New lease. */
struct client_lease *offered_leases; /* Leases offered to us. */
struct client_lease *leases; /* Leases we currently hold. */
struct client_lease *alias; /* Alias lease. */
enum dhcp_state state; /* Current state for this interface. */
struct iaddr destination; /* Where to send packet. */
u_int32_t xid; /* Transaction ID. */
TIME first_sending; /* When was first copy sent? */
TIME interval; /* What's the current resend interval? */
struct string_list *medium; /* Last media type tried. */
struct dhcp_packet packet; /* Outgoing DHCP packet. */
int packet_length; /* Actual length of generated packet. */
struct iaddr requested_address; /* Address we would like to get. */
struct client_config *config; /* Information from config file. */
};
/* Information about each network interface. */
struct interface_info {
struct interface_info *next; /* Next interface in list... */
struct shared_network *shared_network;
/* Networks connected to this interface. */
struct hardware hw_address; /* Its physical address. */
struct in_addr primary_address; /* Primary interface address. */
char name [IFNAMSIZ]; /* Its name... */
int rfdesc; /* Its read file descriptor. */
int wfdesc; /* Its write file descriptor, if
different. */
unsigned char *rbuf; /* Read buffer, if required. */
size_t rbuf_max; /* Size of read buffer. */
size_t rbuf_offset; /* Current offset into buffer. */
size_t rbuf_len; /* Length of data in buffer. */
struct ifreq *ifp; /* Pointer to ifreq struct. */
u_int32_t flags; /* Control flags... */
#define INTERFACE_REQUESTED 1
#define INTERFACE_AUTOMATIC 2
/* Only used by DHCP client code. */
struct client_state *client;
};
struct hardware_link {
struct hardware_link *next;
char name [IFNAMSIZ];
struct hardware address;
};
struct timeout {
struct timeout *next;
TIME when;
void (*func) PROTO ((void *));
void *what;
};
struct protocol {
struct protocol *next;
int fd;
void (*handler) PROTO ((struct protocol *));
void *local;
};
/* Bitmask of dhcp option codes. */
typedef unsigned char option_mask [16];
/* DHCP Option mask manipulation macros... */
#define OPTION_ZERO(mask) (memset (mask, 0, 16))
#define OPTION_SET(mask, bit) (mask [bit >> 8] |= (1 << (bit & 7)))
#define OPTION_CLR(mask, bit) (mask [bit >> 8] &= ~(1 << (bit & 7)))
#define OPTION_ISSET(mask, bit) (mask [bit >> 8] & (1 << (bit & 7)))
#define OPTION_ISCLR(mask, bit) (!OPTION_ISSET (mask, bit))
/* An option occupies its length plus two header bytes (code and
length) for every 255 bytes that must be stored. */
#define OPTION_SPACE(x) ((x) + 2 * ((x) / 255 + 1))
/* Default path to dhcpd config file. */
#ifdef DEBUG
#undef _PATH_DHCPD_CONF
#define _PATH_DHCPD_CONF "dhcpd.conf"
#undef _PATH_DHCPD_DB
#define _PATH_DHCPD_DB "dhcpd.leases"
#else
#ifndef _PATH_DHCPD_CONF
#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
#endif
#ifndef _PATH_DHCPD_DB
#define _PATH_DHCPD_DB "/etc/dhcpd.leases"
#endif
#ifndef _PATH_DHCPD_PID
#define _PATH_DHCPD_PID "/var/run/dhcpd.pid"
#endif
#endif
#ifndef _PATH_DHCLIENT_CONF
#define _PATH_DHCLIENT_CONF "/etc/dhclient.conf"
#endif
#ifndef _PATH_DHCLIENT_PID
#define _PATH_DHCLIENT_PID "/var/run/dhclient.pid"
#endif
#ifndef _PATH_DHCLIENT_DB
#define _PATH_DHCLIENT_DB "/etc/dhclient.leases"
#endif
#ifndef _PATH_RESOLV_CONF
#define _PATH_RESOLV_CONF "/etc/resolv.conf"
#endif
#ifndef _PATH_DHCRELAY_PID
#define _PATH_DHCRELAY_PID "/var/run/dhcrelay.pid"
#endif
#ifndef DHCPD_LOG_FACILITY
#define DHCPD_LOG_FACILITY LOG_DAEMON
#endif
#define MAX_TIME 0x7fffffff
#define MIN_TIME 0
/* External definitions... */
/* options.c */
void parse_options PROTO ((struct packet *));
void parse_option_buffer PROTO ((struct packet *, unsigned char *, int));
int cons_options PROTO ((struct packet *, struct dhcp_packet *,
struct tree_cache **, int, int, int));
int store_options PROTO ((unsigned char *, int, struct tree_cache **,
unsigned char *, int, int, int, int));
char *pretty_print_option PROTO ((unsigned int,
unsigned char *, int, int, int));
void do_packet PROTO ((struct interface_info *,
struct dhcp_packet *, int,
unsigned int, struct iaddr, struct hardware *));
/* errwarn.c */
extern int warnings_occurred;
void error PROTO ((char *, ...));
int warn PROTO ((char *, ...));
int note PROTO ((char *, ...));
int debug PROTO ((char *, ...));
int parse_warn PROTO ((char *, ...));
/* dhcpd.c */
extern TIME cur_time;
extern struct group root_group;
extern u_int16_t local_port;
extern u_int16_t remote_port;
extern int log_priority;
extern int log_perror;
#ifdef USE_FALLBACK
extern struct interface_info fallback_interface;
#endif
extern char *path_dhcpd_conf;
extern char *path_dhcpd_db;
extern char *path_dhcpd_pid;
int main PROTO ((int, char **, char **));
void cleanup PROTO ((void));
void lease_pinged PROTO ((struct iaddr, u_int8_t *, int));
void lease_ping_timeout PROTO ((void *));
/* conflex.c */
extern int lexline, lexchar;
extern char *token_line, *tlname;
extern char comments [4096];
extern int comment_index;
extern int eol_token;
void new_parse PROTO ((char *));
int next_token PROTO ((char **, FILE *));
int peek_token PROTO ((char **, FILE *));
/* confpars.c */
int readconf PROTO ((void));
void read_leases PROTO ((void));
int parse_statement PROTO ((FILE *,
struct group *, int, struct host_decl *, int));
void parse_allow_deny PROTO ((FILE *, struct group *, int));
void skip_to_semi PROTO ((FILE *));
int parse_boolean PROTO ((FILE *));
int parse_semi PROTO ((FILE *));
int parse_lbrace PROTO ((FILE *));
void parse_host_declaration PROTO ((FILE *, struct group *));
char *parse_host_name PROTO ((FILE *));
void parse_class_declaration PROTO ((FILE *, struct group *, int));
void parse_lease_time PROTO ((FILE *, TIME *));
void parse_shared_net_declaration PROTO ((FILE *, struct group *));
void parse_subnet_declaration PROTO ((FILE *, struct shared_network *));
void parse_group_declaration PROTO ((FILE *, struct group *));
void parse_hardware_param PROTO ((FILE *, struct hardware *));
char *parse_string PROTO ((FILE *));
struct tree *parse_ip_addr_or_hostname PROTO ((FILE *, int));
struct tree_cache *parse_fixed_addr_param PROTO ((FILE *));
void parse_option_param PROTO ((FILE *, struct group *));
TIME parse_timestamp PROTO ((FILE *));
struct lease *parse_lease_declaration PROTO ((FILE *));
void parse_address_range PROTO ((FILE *, struct subnet *));
TIME parse_date PROTO ((FILE *));
unsigned char *parse_numeric_aggregate PROTO ((FILE *,
unsigned char *, int *,
int, int, int));
void convert_num PROTO ((unsigned char *, char *, int, int));
/* tree.c */
pair cons PROTO ((caddr_t, pair));
struct tree_cache *tree_cache PROTO ((struct tree *));
struct tree *tree_host_lookup PROTO ((char *));
struct dns_host_entry *enter_dns_host PROTO ((char *));
struct tree *tree_const PROTO ((unsigned char *, int));
struct tree *tree_concat PROTO ((struct tree *, struct tree *));
struct tree *tree_limit PROTO ((struct tree *, int));
int tree_evaluate PROTO ((struct tree_cache *));
/* dhcp.c */
extern int outstanding_pings;
void dhcp PROTO ((struct packet *));
void dhcpdiscover PROTO ((struct packet *));
void dhcprequest PROTO ((struct packet *));
void dhcprelease PROTO ((struct packet *));
void dhcpdecline PROTO ((struct packet *));
void dhcpinform PROTO ((struct packet *));
void nak_lease PROTO ((struct packet *, struct iaddr *cip));
void ack_lease PROTO ((struct packet *, struct lease *, unsigned int, TIME));
void dhcp_reply PROTO ((struct lease *));
struct lease *find_lease PROTO ((struct packet *,
struct shared_network *, int *));
struct lease *mockup_lease PROTO ((struct packet *,
struct shared_network *,
struct host_decl *));
/* bootp.c */
void bootp PROTO ((struct packet *));
/* memory.c */
void enter_host PROTO ((struct host_decl *));
struct host_decl *find_hosts_by_haddr PROTO ((int, unsigned char *, int));
struct host_decl *find_hosts_by_uid PROTO ((unsigned char *, int));
struct subnet *find_host_for_network PROTO ((struct host_decl **,
struct iaddr *,
struct shared_network *));
void new_address_range PROTO ((struct iaddr, struct iaddr,
struct subnet *, int));
extern struct subnet *find_grouped_subnet PROTO ((struct shared_network *,
struct iaddr));
extern struct subnet *find_subnet PROTO ((struct iaddr));
void enter_shared_network PROTO ((struct shared_network *));
void enter_subnet PROTO ((struct subnet *));
void enter_lease PROTO ((struct lease *));
int supersede_lease PROTO ((struct lease *, struct lease *, int));
void release_lease PROTO ((struct lease *));
void abandon_lease PROTO ((struct lease *, char *));
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
struct lease *find_lease_by_hw_addr PROTO ((unsigned char *, int));
struct lease *find_lease_by_ip_addr PROTO ((struct iaddr));
void uid_hash_add PROTO ((struct lease *));
void uid_hash_delete PROTO ((struct lease *));
void hw_hash_add PROTO ((struct lease *));
void hw_hash_delete PROTO ((struct lease *));
struct class *add_class PROTO ((int, char *));
struct class *find_class PROTO ((int, unsigned char *, int));
struct group *clone_group PROTO ((struct group *, char *));
void write_leases PROTO ((void));
void dump_subnets PROTO ((void));
/* alloc.c */
VOIDPTR dmalloc PROTO ((int, char *));
void dfree PROTO ((VOIDPTR, char *));
struct packet *new_packet PROTO ((char *));
struct dhcp_packet *new_dhcp_packet PROTO ((char *));
struct tree *new_tree PROTO ((char *));
struct tree_cache *new_tree_cache PROTO ((char *));
struct hash_table *new_hash_table PROTO ((int, char *));
struct hash_bucket *new_hash_bucket PROTO ((char *));
struct lease *new_lease PROTO ((char *));
struct lease *new_leases PROTO ((int, char *));
struct subnet *new_subnet PROTO ((char *));
struct class *new_class PROTO ((char *));
struct shared_network *new_shared_network PROTO ((char *));
struct group *new_group PROTO ((char *));
struct protocol *new_protocol PROTO ((char *));
struct lease_state *new_lease_state PROTO ((char *));
struct domain_search_list *new_domain_search_list PROTO ((char *));
struct name_server *new_name_server PROTO ((char *));
void free_name_server PROTO ((struct name_server *, char *));
void free_domain_search_list PROTO ((struct domain_search_list *, char *));
void free_lease_state PROTO ((struct lease_state *, char *));
void free_protocol PROTO ((struct protocol *, char *));
void free_group PROTO ((struct group *, char *));
void free_shared_network PROTO ((struct shared_network *, char *));
void free_class PROTO ((struct class *, char *));
void free_subnet PROTO ((struct subnet *, char *));
void free_lease PROTO ((struct lease *, char *));
void free_hash_bucket PROTO ((struct hash_bucket *, char *));
void free_hash_table PROTO ((struct hash_table *, char *));
void free_tree_cache PROTO ((struct tree_cache *, char *));
void free_packet PROTO ((struct packet *, char *));
void free_dhcp_packet PROTO ((struct dhcp_packet *, char *));
void free_tree PROTO ((struct tree *, char *));
/* print.c */
char *print_hw_addr PROTO ((int, int, unsigned char *));
void print_lease PROTO ((struct lease *));
void dump_raw PROTO ((unsigned char *, int));
void dump_packet PROTO ((struct packet *));
void hash_dump PROTO ((struct hash_table *));
/* socket.c */
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
|| defined (USE_SOCKET_FALLBACK)
int if_register_socket PROTO ((struct interface_info *));
#endif
#ifdef USE_SOCKET_FALLBACK
void if_reinitialize_fallback PROTO ((struct interface_info *));
void if_register_fallback PROTO ((struct interface_info *));
ssize_t send_fallback PROTO ((struct interface_info *,
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
void fallback_discard PROTO ((struct protocol *));
#endif
#ifdef USE_SOCKET_SEND
void if_reinitialize_send PROTO ((struct interface_info *));
void if_register_send PROTO ((struct interface_info *));
ssize_t send_packet PROTO ((struct interface_info *,
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
#endif
#ifdef USE_SOCKET_RECEIVE
void if_reinitialize_receive PROTO ((struct interface_info *));
void if_register_receive PROTO ((struct interface_info *));
ssize_t receive_packet PROTO ((struct interface_info *,
unsigned char *, size_t,
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
void if_enable PROTO ((struct interface_info *));
#endif
/* bpf.c */
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
int if_register_bpf PROTO ( (struct interface_info *));
#endif
#ifdef USE_BPF_SEND
void if_reinitialize_send PROTO ((struct interface_info *));
void if_register_send PROTO ((struct interface_info *));
ssize_t send_packet PROTO ((struct interface_info *,
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
#endif
#ifdef USE_BPF_RECEIVE
void if_reinitialize_receive PROTO ((struct interface_info *));
void if_register_receive PROTO ((struct interface_info *));
ssize_t receive_packet PROTO ((struct interface_info *,
unsigned char *, size_t,
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_BPF_SEND)
void if_enable PROTO ((struct interface_info *));
#endif
/* nit.c */
#if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE)
int if_register_nit PROTO ( (struct interface_info *));
#endif
#ifdef USE_NIT_SEND
void if_reinitialize_send PROTO ((struct interface_info *));
void if_register_send PROTO ((struct interface_info *));
ssize_t send_packet PROTO ((struct interface_info *,
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
#endif
#ifdef USE_NIT_RECEIVE
void if_reinitialize_receive PROTO ((struct interface_info *));
void if_register_receive PROTO ((struct interface_info *));
ssize_t receive_packet PROTO ((struct interface_info *,
unsigned char *, size_t,
struct sockaddr_in *, struct hardware *));
#endif
#if defined (USE_BPF_SEND)
void if_enable PROTO ((struct interface_info *));
#endif
/* raw.c */
#ifdef USE_RAW_SEND
void if_reinitialize_send PROTO ((struct interface_info *));
void if_register_send PROTO ((struct interface_info *));
ssize_t send_packet PROTO ((struct interface_info *,
struct packet *, struct dhcp_packet *, size_t,
struct in_addr,
struct sockaddr_in *, struct hardware *));
#endif
/* dispatch.c */
extern struct interface_info *interfaces, *dummy_interfaces;
extern struct protocol *protocols;
extern int quiet_interface_discovery;
extern void (*bootp_packet_handler) PROTO ((struct interface_info *,
struct dhcp_packet *, int,
unsigned int,
struct iaddr, struct hardware *));
extern struct timeout *timeouts;
void discover_interfaces PROTO ((int));
void reinitialize_interfaces PROTO ((void));
void dispatch PROTO ((void));
int locate_network PROTO ((struct packet *));
void add_timeout PROTO ((TIME, void (*) PROTO ((void *)), void *));
#if 0
void add_fast_timeout PROTO ((UTIME, void (*) PROTO ((void *)), void *));
#endif
void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *));
void add_protocol PROTO ((char *, int,
void (*) PROTO ((struct protocol *)), void *));
void remove_protocol PROTO ((struct protocol *));
/* hash.c */
struct hash_table *new_hash PROTO ((void));
void add_hash PROTO ((struct hash_table *, unsigned char *,
int, unsigned char *));
void delete_hash_entry PROTO ((struct hash_table *, unsigned char *, int));
unsigned char *hash_lookup PROTO ((struct hash_table *, unsigned char *, int));
/* tables.c */
extern struct option dhcp_options [256];
extern unsigned char dhcp_option_default_priority_list [];
extern int sizeof_dhcp_option_default_priority_list;
extern char *hardware_types [256];
extern struct hash_table universe_hash;
extern struct universe dhcp_universe;
void initialize_universes PROTO ((void));
/* convert.c */
u_int32_t getULong PROTO ((unsigned char *));
int32_t getLong PROTO ((unsigned char *));
u_int16_t getUShort PROTO ((unsigned char *));
int16_t getShort PROTO ((unsigned char *));
void putULong PROTO ((unsigned char *, u_int32_t));
void putLong PROTO ((unsigned char *, int32_t));
void putUShort PROTO ((unsigned char *, unsigned int));
void putShort PROTO ((unsigned char *, int));
/* inet.c */
struct iaddr subnet_number PROTO ((struct iaddr, struct iaddr));
struct iaddr ip_addr PROTO ((struct iaddr, struct iaddr, u_int32_t));
struct iaddr broadcast_addr PROTO ((struct iaddr, struct iaddr));
u_int32_t host_addr PROTO ((struct iaddr, struct iaddr));
int addr_eq PROTO ((struct iaddr, struct iaddr));
char *piaddr PROTO ((struct iaddr));
/* dhclient.c */
extern char *path_dhclient_conf;
extern char *path_dhclient_db;
extern char *path_dhclient_pid;
extern int interfaces_requested;
extern struct client_config top_level_config;
void dhcpoffer PROTO ((struct packet *));
void dhcpack PROTO ((struct packet *));
void dhcpnak PROTO ((struct packet *));
void send_discover PROTO ((void *));
void send_request PROTO ((void *));
void send_release PROTO ((void *));
void send_decline PROTO ((void *));
void state_reboot PROTO ((void *));
void state_init PROTO ((void *));
void state_selecting PROTO ((void *));
void state_requesting PROTO ((void *));
void state_bound PROTO ((void *));
void state_panic PROTO ((void *));
void bind_lease PROTO ((struct interface_info *));
void make_discover PROTO ((struct interface_info *, struct client_lease *));
void make_request PROTO ((struct interface_info *, struct client_lease *));
void make_decline PROTO ((struct interface_info *, struct client_lease *));
void make_release PROTO ((struct interface_info *, struct client_lease *));
void free_client_lease PROTO ((struct client_lease *));
void rewrite_client_leases PROTO ((void));
void write_client_lease PROTO ((struct interface_info *,
struct client_lease *));
char *dhcp_option_ev_name PROTO ((struct option *));
void script_init PROTO ((struct interface_info *, char *,
struct string_list *));
void script_write_params PROTO ((struct interface_info *,
char *, struct client_lease *));
int script_go PROTO ((struct interface_info *));
struct client_lease *packet_to_lease PROTO ((struct packet *));
void go_daemon PROTO ((void));
void write_client_pid_file PROTO ((void));
void status_message PROTO ((struct sysconf_header *, void *));
void client_location_changed PROTO ((void));
/* db.c */
int write_lease PROTO ((struct lease *));
int commit_leases PROTO ((void));
void db_startup PROTO ((void));
void new_lease_file PROTO ((void));
/* packet.c */
u_int32_t checksum PROTO ((unsigned char *, int, u_int32_t));
u_int32_t wrapsum PROTO ((u_int32_t));
void assemble_hw_header PROTO ((struct interface_info *, unsigned char *,
int *, struct hardware *));
void assemble_udp_ip_header PROTO ((struct interface_info *, unsigned char *,
int *, u_int32_t, u_int32_t, unsigned int,
unsigned char *, int));
ssize_t decode_hw_header PROTO ((struct interface_info *, unsigned char *,
int, struct hardware *));
ssize_t decode_udp_ip_header PROTO ((struct interface_info *, unsigned char *,
int, struct sockaddr_in *,
unsigned char *, int));
/* dhxpxlt.c */
void convert_statement PROTO ((FILE *));
void convert_host_statement PROTO ((FILE *, jrefproto));
void convert_host_name PROTO ((FILE *, jrefproto));
void convert_class_statement PROTO ((FILE *, jrefproto, int));
void convert_class_decl PROTO ((FILE *, jrefproto));
void convert_lease_time PROTO ((FILE *, jrefproto, char *));
void convert_shared_net_statement PROTO ((FILE *, jrefproto));
void convert_subnet_statement PROTO ((FILE *, jrefproto));
void convert_subnet_decl PROTO ((FILE *, jrefproto));
void convert_host_decl PROTO ((FILE *, jrefproto));
void convert_hardware_decl PROTO ((FILE *, jrefproto));
void convert_hardware_addr PROTO ((FILE *, jrefproto));
void convert_filename_decl PROTO ((FILE *, jrefproto));
void convert_servername_decl PROTO ((FILE *, jrefproto));
void convert_ip_addr_or_hostname PROTO ((FILE *, jrefproto, int));
void convert_fixed_addr_decl PROTO ((FILE *, jrefproto));
void convert_option_decl PROTO ((FILE *, jrefproto));
void convert_timestamp PROTO ((FILE *, jrefproto));
void convert_lease_statement PROTO ((FILE *, jrefproto));
void convert_address_range PROTO ((FILE *, jrefproto));
void convert_date PROTO ((FILE *, jrefproto, char *));
void convert_numeric_aggregate PROTO ((FILE *, jrefproto, int, int, int, int));
void indent PROTO ((int));
/* route.c */
void add_route_direct PROTO ((struct interface_info *, struct in_addr));
void add_route_net PROTO ((struct interface_info *, struct in_addr,
struct in_addr));
void add_route_default_gateway PROTO ((struct interface_info *,
struct in_addr));
void remove_routes PROTO ((struct in_addr));
void remove_if_route PROTO ((struct interface_info *, struct in_addr));
void remove_all_if_routes PROTO ((struct interface_info *));
void set_netmask PROTO ((struct interface_info *, struct in_addr));
void set_broadcast_addr PROTO ((struct interface_info *, struct in_addr));
void set_ip_address PROTO ((struct interface_info *, struct in_addr));
/* clparse.c */
int read_client_conf PROTO ((void));
void read_client_leases PROTO ((void));
void parse_client_statement PROTO ((FILE *, struct interface_info *,
struct client_config *));
int parse_X PROTO ((FILE *, u_int8_t *, int));
int parse_option_list PROTO ((FILE *, u_int8_t *));
void parse_interface_declaration PROTO ((FILE *, struct client_config *));
struct interface_info *interface_or_dummy PROTO ((char *));
void make_client_state PROTO ((struct interface_info *));
void make_client_config PROTO ((struct interface_info *,
struct client_config *));
void parse_client_lease_statement PROTO ((FILE *, int));
void parse_client_lease_declaration PROTO ((FILE *, struct client_lease *,
struct interface_info **));
struct option *parse_option_decl PROTO ((FILE *, struct option_data *));
void parse_string_list PROTO ((FILE *, struct string_list **, int));
int parse_ip_addr PROTO ((FILE *, struct iaddr *));
void parse_reject_statement PROTO ((FILE *, struct client_config *));
/* dhcrelay.c */
void relay PROTO ((struct interface_info *, struct dhcp_packet *, int,
unsigned int, struct iaddr, struct hardware *));
/* icmp.c */
void icmp_startup PROTO ((int, void (*) PROTO ((struct iaddr,
u_int8_t *, int))));
int icmp_echorequest PROTO ((struct iaddr *));
void icmp_echoreply PROTO ((struct protocol *));
/* dns.c */
void dns_startup PROTO ((void));
int ns_inaddr_lookup PROTO ((u_int16_t, struct iaddr));
void dns_packet PROTO ((struct protocol *));
/* resolv.c */
extern char path_resolv_conf [];
struct name_server *name_servers;
struct domain_search_list *domains;
void read_resolv_conf PROTO ((TIME));
struct sockaddr_in *pick_name_server PROTO ((void));
/* inet_addr.c */
#ifdef NEED_INET_ATON
int inet_aton PROTO ((const char *, struct in_addr *));
#endif
/* sysconf.c */
void sysconf_startup PROTO ((void (*) (struct sysconf_header *, void *)));
void sysconf_restart PROTO ((void *));
void sysconf_message PROTO ((struct protocol *proto));

View File

@ -0,0 +1,131 @@
/* dhctoken.h
Tokens for config file lexer and parser. */
/*
* Copyright (c) 1995, 1996, 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#define SEMI ';'
#define DOT '.'
#define COLON ':'
#define COMMA ','
#define SLASH '/'
#define LBRACE '{'
#define RBRACE '}'
#define FIRST_TOKEN HOST
#define HOST 256
#define HARDWARE 257
#define FILENAME 258
#define FIXED_ADDR 259
#define OPTION 260
#define ETHERNET 261
#define STRING 262
#define NUMBER 263
#define NUMBER_OR_NAME 264
#define NAME 265
#define TIMESTAMP 266
#define STARTS 267
#define ENDS 268
#define UID 269
#define CLASS 270
#define LEASE 271
#define RANGE 272
#define PACKET 273
#define CIADDR 274
#define YIADDR 275
#define SIADDR 276
#define GIADDR 277
#define SUBNET 278
#define NETMASK 279
#define DEFAULT_LEASE_TIME 280
#define MAX_LEASE_TIME 281
#define VENDOR_CLASS 282
#define USER_CLASS 283
#define SHARED_NETWORK 284
#define SERVER_NAME 285
#define DYNAMIC_BOOTP 286
#define SERVER_IDENTIFIER 287
#define DYNAMIC_BOOTP_LEASE_CUTOFF 288
#define DYNAMIC_BOOTP_LEASE_LENGTH 289
#define BOOT_UNKNOWN_CLIENTS 290
#define NEXT_SERVER 291
#define TOKEN_RING 292
#define GROUP 293
#define ONE_LEASE_PER_CLIENT 294
#define GET_LEASE_HOSTNAMES 295
#define USE_HOST_DECL_NAMES 296
#define SEND 297
#define CLIENT_IDENTIFIER 298
#define REQUEST 299
#define REQUIRE 300
#define TIMEOUT 301
#define RETRY 302
#define SELECT_TIMEOUT 303
#define SCRIPT 304
#define INTERFACE 305
#define RENEW 306
#define REBIND 307
#define EXPIRE 308
#define UNKNOWN_CLIENTS 309
#define ALLOW 310
#define BOOTP 311
#define DENY 312
#define BOOTING 313
#define DEFAULT 314
#define MEDIA 315
#define MEDIUM 316
#define ALIAS 317
#define REBOOT 318
#define ABANDONED 319
#define BACKOFF_CUTOFF 320
#define INITIAL_INTERVAL 321
#define NAMESERVER 322
#define DOMAIN 323
#define SEARCH 324
#define SUPERSEDE 325
#define APPEND 326
#define PREPEND 327
#define HOSTNAME 328
#define CLIENT_HOSTNAME 329
#define REJECT 330
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
(x) != STRING && \
(x) != NUMBER && \
(x) != EOF)

View File

@ -0,0 +1,56 @@
/* hash.h
Definitions for hashing... */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#define DEFAULT_HASH_SIZE 97
struct hash_bucket {
struct hash_bucket *next;
unsigned char *name;
int len;
unsigned char *value;
};
struct hash_table {
int hash_count;
struct hash_bucket *buckets [DEFAULT_HASH_SIZE];
};

View File

@ -0,0 +1,52 @@
/* inet.h
Portable definitions for internet addresses */
/*
* Copyright (c) 1996 The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
/* An internet address of up to 128 bits. */
struct iaddr {
int len;
unsigned char iabuf [16];
};
struct iaddrlist {
struct iaddrlist *next;
struct iaddr addr;
};

View File

@ -0,0 +1,74 @@
/* $NetBSD: if_ether.h,v 1.20 1995/06/12 00:47:27 mycroft Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)if_ether.h 8.1 (Berkeley) 6/10/93
*/
/*
* Ethernet address - 6 octets
* this is only used by the ethers(3) functions.
*/
struct ether_addr {
u_int8_t ether_addr_octet[6];
};
/*
* Structure of a 10Mb/s Ethernet header.
*/
#define ETHER_ADDR_LEN 6
struct ether_header {
u_int8_t ether_dhost[ETHER_ADDR_LEN];
u_int8_t ether_shost[ETHER_ADDR_LEN];
u_int16_t ether_type;
};
#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
#define ETHERTYPE_IP 0x0800 /* IP protocol */
#define ETHERTYPE_ARP 0x0806 /* address resolution protocol */
#define ETHERTYPE_REVARP 0x8035 /* reverse addr resolution protocol */
/*
* The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
* (type-ETHERTYPE_TRAIL)*512 bytes of data followed
* by an ETHER type (as given above) and then the (variable-length) header.
*/
#define ETHERTYPE_TRAIL 0x1000 /* Trailer packet */
#define ETHERTYPE_NTRAILER 16
#define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
#define ETHERMTU 1500
#define ETHERMIN (60-14)

View File

@ -0,0 +1,171 @@
/* $NetBSD: ip.h,v 1.9 1995/05/15 01:22:44 cgd Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ip.h 8.1 (Berkeley) 6/10/93
*/
/*
* Definitions for internet protocol version 4.
* Per RFC 791, September 1981.
*/
#define IPVERSION 4
/*
* Structure of an internet header, naked of options.
*
* We declare ip_len and ip_off to be short, rather than u_short
* pragmatically since otherwise unsigned comparisons can result
* against negative integers quite easily, and fail in subtle ways.
*/
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
u_int8_t ip_hl:4, /* header length */
ip_v:4; /* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t ip_v:4, /* version */
ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
int16_t ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_int16_t ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
#define IP_MAXPACKET 65535 /* maximum packet size */
/*
* Definitions for IP type of service (ip_tos)
*/
#define IPTOS_LOWDELAY 0x10
#define IPTOS_THROUGHPUT 0x08
#define IPTOS_RELIABILITY 0x04
/* IPTOS_LOWCOST 0x02 XXX */
/*
* Definitions for IP precedence (also in ip_tos) (hopefully unused)
*/
#define IPTOS_PREC_NETCONTROL 0xe0
#define IPTOS_PREC_INTERNETCONTROL 0xc0
#define IPTOS_PREC_CRITIC_ECP 0xa0
#define IPTOS_PREC_FLASHOVERRIDE 0x80
#define IPTOS_PREC_FLASH 0x60
#define IPTOS_PREC_IMMEDIATE 0x40
#define IPTOS_PREC_PRIORITY 0x20
#define IPTOS_PREC_ROUTINE 0x00
/*
* Definitions for options.
*/
#define IPOPT_COPIED(o) ((o)&0x80)
#define IPOPT_CLASS(o) ((o)&0x60)
#define IPOPT_NUMBER(o) ((o)&0x1f)
#define IPOPT_CONTROL 0x00
#define IPOPT_RESERVED1 0x20
#define IPOPT_DEBMEAS 0x40
#define IPOPT_RESERVED2 0x60
#define IPOPT_EOL 0 /* end of option list */
#define IPOPT_NOP 1 /* no operation */
#define IPOPT_RR 7 /* record packet route */
#define IPOPT_TS 68 /* timestamp */
#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
#define IPOPT_LSRR 131 /* loose source route */
#define IPOPT_SATID 136 /* satnet id */
#define IPOPT_SSRR 137 /* strict source route */
/*
* Offsets to fields in options other than EOL and NOP.
*/
#define IPOPT_OPTVAL 0 /* option ID */
#define IPOPT_OLEN 1 /* option length */
#define IPOPT_OFFSET 2 /* offset within option */
#define IPOPT_MINOFF 4 /* min value of above */
/*
* Time stamp option structure.
*/
struct ip_timestamp {
u_int8_t ipt_code; /* IPOPT_TS */
u_int8_t ipt_len; /* size of structure (variable) */
u_int8_t ipt_ptr; /* index of current entry */
#if BYTE_ORDER == LITTLE_ENDIAN
u_int8_t ipt_flg:4, /* flags, see below */
ipt_oflw:4; /* overflow counter */
#endif
#if BYTE_ORDER == BIG_ENDIAN
u_int8_t ipt_oflw:4, /* overflow counter */
ipt_flg:4; /* flags, see below */
#endif
union ipt_timestamp {
u_int32_t ipt_time[1];
struct ipt_ta {
struct in_addr ipt_addr;
u_int32_t ipt_time;
} ipt_ta[1];
} ipt_timestamp;
};
/* flag bits for ipt_flg */
#define IPOPT_TS_TSONLY 0 /* timestamps only */
#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
#define IPOPT_TS_PRESPEC 3 /* specified modules only */
/* bits for security (not byte swapped) */
#define IPOPT_SECUR_UNCLASS 0x0000
#define IPOPT_SECUR_CONFID 0xf135
#define IPOPT_SECUR_EFTO 0x789a
#define IPOPT_SECUR_MMMM 0xbc4d
#define IPOPT_SECUR_RESTR 0xaf13
#define IPOPT_SECUR_SECRET 0xd788
#define IPOPT_SECUR_TOPSECRET 0x6bc5
/*
* Internet implementation parameters.
*/
#define MAXTTL 255 /* maximum time to live (seconds) */
#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
#define IPFRAGTTL 60 /* time to live for frags, slowhz */
#define IPTTLDEC 1 /* subtracted when forwarding */
#define IP_MSS 576 /* default maximum segment size */

View File

@ -0,0 +1,182 @@
/* $NetBSD: ip_icmp.h,v 1.11 1996/08/03 15:48:18 neil Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
*/
/*
* Interface Control Message Protocol Definitions.
* Per RFC 792, September 1981.
*/
/*
* Internal of an ICMP Router Advertisement
*/
struct icmp_ra_addr {
u_int32_t ira_addr;
u_int32_t ira_preference;
};
/*
* Structure of an icmp header.
*/
struct icmp {
u_int8_t icmp_type; /* type of message, see below */
u_int8_t icmp_code; /* type sub code */
u_int16_t icmp_cksum; /* ones complement cksum of struct */
union {
u_int8_t ih_pptr; /* ICMP_PARAMPROB */
struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
struct ih_idseq {
int16_t icd_id;
int16_t icd_seq;
} ih_idseq;
int32_t ih_void;
/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
struct ih_pmtu {
int16_t ipm_void;
int16_t ipm_nextmtu;
} ih_pmtu;
struct ih_rtradv {
u_int8_t irt_num_addrs;
u_int8_t irt_wpa;
u_int16_t irt_lifetime;
} ih_rtradv;
} icmp_hun;
#define icmp_pptr icmp_hun.ih_pptr
#define icmp_gwaddr icmp_hun.ih_gwaddr
#define icmp_id icmp_hun.ih_idseq.icd_id
#define icmp_seq icmp_hun.ih_idseq.icd_seq
#define icmp_void icmp_hun.ih_void
#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
union {
struct id_ts {
u_int32_t its_otime;
u_int32_t its_rtime;
u_int32_t its_ttime;
} id_ts;
struct id_ip {
struct ip idi_ip;
/* options and then 64 bits of data */
} id_ip;
struct icmp_ra_addr id_radv;
u_int32_t id_mask;
int8_t id_data[1];
} icmp_dun;
#define icmp_otime icmp_dun.id_ts.its_otime
#define icmp_rtime icmp_dun.id_ts.its_rtime
#define icmp_ttime icmp_dun.id_ts.its_ttime
#define icmp_ip icmp_dun.id_ip.idi_ip
#define icmp_radv icmp_dun.id_mask
#define icmp_mask icmp_dun.id_mask
#define icmp_data icmp_dun.id_data
};
/*
* Lower bounds on packet lengths for various types.
* For the error advice packets must first insure that the
* packet is large enought to contain the returned ip header.
* Only then can we do the check to see if 64 bits of packet
* data have been returned, since we need to check the returned
* ip header length.
*/
#define ICMP_MINLEN 8 /* abs minimum */
#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */
#define ICMP_MASKLEN 12 /* address mask */
#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
/* N.B.: must separately check that ip_hl >= 5 */
/*
* Definition of type and code field values.
*/
#define ICMP_ECHOREPLY 0 /* echo reply */
#define ICMP_UNREACH 3 /* dest unreachable, codes: */
#define ICMP_UNREACH_NET 0 /* bad net */
#define ICMP_UNREACH_HOST 1 /* bad host */
#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
#define ICMP_UNREACH_PORT 3 /* bad port */
#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */
#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
#define ICMP_REDIRECT 5 /* shorter route, codes: */
#define ICMP_REDIRECT_NET 0 /* for network */
#define ICMP_REDIRECT_HOST 1 /* for host */
#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
#define ICMP_ECHO 8 /* echo service */
#define ICMP_ROUTERADVERT 9 /* router advertisement */
#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
#define ICMP_TIMXCEED 11 /* time exceeded, code: */
#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
#define ICMP_PARAMPROB 12 /* ip header bad */
#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
#define ICMP_TSTAMP 13 /* timestamp request */
#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
#define ICMP_IREQ 15 /* information request */
#define ICMP_IREQREPLY 16 /* information reply */
#define ICMP_MASKREQ 17 /* address mask request */
#define ICMP_MASKREPLY 18 /* address mask reply */
#define ICMP_MAXTYPE 18
#define ICMP_INFOTYPE(type) \
((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
(type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
#ifdef _KERNEL
void icmp_error __P((struct mbuf *, int, int, n_long, struct ifnet *));
void icmp_input __P((struct mbuf *, ...));
void icmp_reflect __P((struct mbuf *));
void icmp_send __P((struct mbuf *, struct mbuf *));
int icmp_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
#endif

View File

@ -0,0 +1,47 @@
/* $NetBSD: udp.h,v 1.6 1995/04/13 06:37:10 cgd Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)udp.h 8.1 (Berkeley) 6/10/93
*/
/*
* Udp protocol header.
* Per RFC 768, September, 1981.
*/
struct udphdr {
u_int16_t uh_sport; /* source port */
u_int16_t uh_dport; /* destination port */
int16_t uh_ulen; /* udp length */
u_int16_t uh_sum; /* udp checksum */
};

View File

@ -0,0 +1,220 @@
/* osdep.h
Operating system dependencies... */
/*
* Copyright (c) 1996, 1997, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE INTERNET SOFTWARE CONSORTIUM OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software was written for the Internet Software Consortium by Ted Lemon
* under a contract with Vixie Laboratories.
*/
#include "site.h"
/* Porting::
If you add a new network API, you must add a check for it below: */
#if !defined (USE_SOCKETS) && \
!defined (USE_SOCKET_SEND) && \
!defined (USE_SOCKET_RECEIVE) && \
!defined (USE_RAW_SOCKETS) && \
!defined (USE_RAW_SEND) && \
!defined (USE_SOCKET_RECEIVE) && \
!defined (USE_BPF) && \
!defined (USE_BPF_SEND) && \
!defined (USE_BPF_RECEIVE) && \
!defined (USE_NIT) && \
!defined (USE_NIT_SEND) && \
!defined (USE_NIT_RECEIVE) && \
!defined (USR_DLPI_SEND) && \
!defined (USE_DLPI_RECEIVE)
# define USE_DEFAULT_NETWORK
#endif
/* Porting::
If you add a new system configuration file, include it here: */
#if defined (sun)
# if defined (__svr4__) || defined (__SVR4)
# include "cf/sunos5-5.h"
# else
# include "cf/sunos4.h"
# endif
#endif
#ifdef bsdi
# include "cf/bsdos.h"
#endif
#ifdef __NetBSD__
# include "cf/netbsd.h"
#endif
#ifdef __FreeBSD__
# include "cf/freebsd.h"
#endif
#if defined (__osf__) && defined (__alpha)
# include "cf/alphaosf.h"
#endif
#ifdef ultrix
# include "cf/ultrix.h"
#endif
#ifdef linux
# include "cf/linux.h"
#endif
#ifdef SCO
# include "cf/sco.h"
#endif
#ifdef hpux
# include "cf/hpux.h"
#endif
#ifdef __QNX__
# include "cf/qnx.h"
#endif
#ifdef __CYGWIN32__
# include "cf/cygwin32.h"
#endif
#ifdef NeXT
# ifdef __APPLE__
# include "cf/rhapsody.h"
# else
# include "cf/nextstep.h"
# endif
#endif
/* Porting::
If you add a new network API, and have it set up so that it can be
used for sending or receiving, but doesn't have to be used for both,
then set up an ifdef like the ones below: */
#ifdef USE_SOCKETS
# define USE_SOCKET_SEND
# define USE_SOCKET_RECEIVE
#endif
#ifdef USE_RAW_SOCKETS
# define USE_RAW_SEND
# define USE_SOCKET_RECEIVE
#endif
#ifdef USE_BPF
# define USE_BPF_SEND
# define USE_BPF_RECEIVE
#endif
#ifdef USE_NIT
# define USE_NIT_SEND
# define USE_NIT_RECEIVE
#endif
#ifdef USE_DLPI
# define USE_DLPI_SEND
# define USE_DLPI_RECEIVE
#endif
#ifdef USE_UPF
# define USE_UPF_SEND
# define USE_UPF_RECEIVE
#endif
/* Porting::
If you add support for sending packets directly out an interface,
and your support does not do ARP or routing, you must use a fallback
mechanism to deal with packets that need to be sent to routers.
Currently, all low-level packet interfaces use BSD sockets as a
fallback. */
#if defined (USE_BPF_SEND) || defined (USE_NIT_SEND) || \
defined (USE_DLPI_SEND) || defined (USE_UPF_SEND)
# define USE_SOCKET_FALLBACK
# define USE_FALLBACK
#endif
/* Porting::
If you add support for sending packets directly out an interface
and need to be able to assemble packets, add the USE_XXX_SEND
definition for your interface to the list tested below. */
#if defined (USE_RAW_SEND) || defined (USE_BPF_SEND) || \
defined (USE_NIT_SEND) || defined (USE_UPF_SEND) || \
defined (USE_DLPI_SEND)
# define PACKET_ASSEMBLY
#endif
/* Porting::
If you add support for receiving packets directly from an interface
and need to be able to decode raw packets, add the USE_XXX_RECEIVE
definition for your interface to the list tested below. */
#if defined (USE_RAW_RECEIVE) || defined (USE_BPF_SEND) || \
defined (USE_NIT_RECEIVE) || defined (USE_UPF_RECEIVE) || \
defined (USE_DLPI_RECEIVE)
# define PACKET_DECODING
#endif
/* If we don't have a DLPI packet filter, we have to filter in userland.
Probably not worth doing, actually. */
#if defined (USE_DLPI_RECEIVE) && !defined (USE_DLPI_PFMOD)
# define USERLAND_FILTER
#endif
/* jmp_buf is assumed to be a struct unless otherwise defined in the
system header. */
#ifndef jbp_decl
# define jbp_decl(x) jmp_buf *x
#endif
#ifndef jref
# define jref(x) (&(x))
#endif
#ifndef jdref
# define jdref(x) (*(x))
#endif
#ifndef jrefproto
# define jrefproto jmp_buf *
#endif
#ifndef BPF_FORMAT
# define BPF_FORMAT "/dev/bpf%d"
#endif

View File

@ -0,0 +1,100 @@
/* Site-specific definitions.
For supported systems, you shouldn't need to make any changes here.
However, you may want to, in order to deal with site-specific
differences. */
/* Add any site-specific definitions and inclusions here... */
/* #include <site-foo-bar.h> */
/* #define SITE_FOOBAR */
/* Define this if you don't want dhcpd to run as a daemon and do want
to see all its output printed to stdout instead of being logged via
syslog(). This also makes dhcpd use the dhcpd.conf in its working
directory and write the dhcpd.leases file there. */
/* #define DEBUG */
/* Define this to see what the parser is parsing. You probably don't
want to see this. */
/* #define DEBUG_TOKENS */
/* Define this to see dumps of incoming and outgoing packets. This
slows things down quite a bit... */
/* #define DEBUG_PACKET */
/* Define this if you want to see dumps of tree evaluations. The most
common reason for doing this is to watch what happens with DNS name
lookups. */
/* #define DEBUG_EVAL */
/* Define this if you want the dhcpd.pid file to go somewhere other than
the default (which varies from system to system, but is usually either
/etc or /var/run. */
/* #define _PATH_DHCPD_PID "/var/run/dhcpd.pid" */
/* Define this if you want the dhcpd.leases file (the dynamic lease database)
to go somewhere other than the default location, which is normally
/etc/dhcpd.leases. */
/* #define _PATH_DHCPD_DB "/etc/dhcpd.leases" */
/* Define this if you want the dhcpd.conf file to go somewhere other than
the default location. By default, it goes in /etc/dhcpd.conf. */
/* #define _PATH_DHCPD_CONF "/etc/dhcpd.conf" */
/* Network API definitions. You do not need to choose one of these - if
you don't choose, one will be chosen for you in your system's config
header. DON'T MESS WITH THIS UNLESS YOU KNOW WHAT YOU'RE DOING!!! */
/* Define this to use the standard BSD socket API.
On many systems, the BSD socket API does not provide the ability to
send packets to the 255.255.255.255 broadcast address, which can
prevent some clients (e.g., Win95) from seeing replies. This is
not a problem on Solaris.
In addition, the BSD socket API will not work when more than one
network interface is configured on the server.
However, the BSD socket API is about as efficient as you can get, so if
the aforementioned problems do not matter to you, or if no other
API is supported for your system, you may want to go with it. */
/* #define USE_SOCKETS */
/* Define this to use the Sun Streams NIT API.
The Sun Streams NIT API is only supported on SunOS 4.x releases. */
/* #define USE_NIT */
/* Define this to use the Berkeley Packet Filter API.
The BPF API is available on all 4.4-BSD derivatives, including
NetBSD, FreeBSD and BSDI's BSD/OS. It's also available on
DEC Alpha OSF/1 in a compatibility mode supported by the Alpha OSF/1
packetfilter interface. */
/* #define USE_BPF */
/* Define this to use the raw socket API.
The raw socket API is provided on many BSD derivatives, and provides
a way to send out raw IP packets. It is only supported for sending
packets - packets must be received with the regular socket API.
This code is experimental - I've never gotten it to actually transmit
a packet to the 255.255.255.255 broadcast address - so use it at your
own risk. */
/* #define USE_RAW_SOCKETS */
/* Define this to change the logging facility used by dhcpd. */
/* #define DHCPD_LOG_FACILITY LOG_DAEMON */

View File

@ -0,0 +1,52 @@
/* systat.h
Definitions for systat protocol... */
/*
* Copyright (c) 1997 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#define SYSCONF_SOCKET "/var/run/sysconf"
struct sysconf_header {
u_int32_t type; /* Type of status message... */
u_int32_t length; /* Length of message. */
};
/* Message types... */
#define NETWORK_LOCATION_CHANGED 1

View File

@ -0,0 +1,107 @@
/* tree.h
Definitions for address trees... */
/*
* Copyright (c) 1995 The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
/* A pair of pointers, suitable for making a linked list. */
typedef struct _pair {
caddr_t car;
struct _pair *cdr;
} *pair;
/* Tree node types... */
#define TREE_CONCAT 1
#define TREE_HOST_LOOKUP 2
#define TREE_CONST 3
#define TREE_LIMIT 4
/* Tree structure for deferred evaluation of changing values. */
struct tree {
int op;
union {
struct concat {
struct tree *left;
struct tree *right;
} concat;
struct host_lookup {
struct dns_host_entry *host;
} host_lookup;
struct const_val {
unsigned char *data;
int len;
} const_val;
struct limit {
struct tree *tree;
int limit;
} limit;
} data;
};
/* DNS host entry structure... */
struct dns_host_entry {
char *hostname;
unsigned char *data;
int data_len;
int buf_len;
TIME timeout;
};
struct tree_cache {
unsigned char *value;
int len;
int buf_size;
TIME timeout;
struct tree *tree;
int flags;
#define TC_AWAITING_RESOLUTION 1
#define TC_TEMPORARY 2
};
struct universe {
char *name;
struct hash_table *hash;
struct option *options [256];
};
struct option {
char *name;
char *format;
struct universe *universe;
unsigned char code;
};