mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcb29ac16c |
No files matched your search
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,104 +0,0 @@
|
||||
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.
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
# ex:ts=8
|
||||
|
||||
ISC DHCP client 2.0b1pl11
|
||||
originals can be found at: ftp://ftp.isc.org/isc/dhcp/
|
||||
|
||||
|
||||
For the import of ISC-dhclient the following files were removed:
|
||||
Makefile.conf Makefile.dist configure
|
||||
docs/* relay/* server/*
|
||||
|
||||
client/
|
||||
Makefile.dist dhclient-script.cat8 dhclient.cat8
|
||||
dhclient.conf.cat5 dhclient.leases.cat5
|
||||
|
||||
client/scripts/
|
||||
bsdos linux netbsd
|
||||
nextstep solaris
|
||||
|
||||
common/
|
||||
Makefile.dist dhcp-options.cat5
|
||||
|
||||
include/cf/
|
||||
alphaosf.h bsdos.h cygwin32.h
|
||||
hpux.h linux.h netbsd.h
|
||||
nextstep.h qnx.h rhapsody.h
|
||||
sample.h sco.h sunos4.h
|
||||
sunos5-5.h ultrix.h
|
||||
|
||||
|
||||
Imported by:
|
||||
|
||||
cvs import -ko -m 'Virgin import of ISC-DHCP v2.0b1pl11' \
|
||||
src/contrib/isc-dhcp ISC isc_dhcp_2_0_b_1_pl_11
|
||||
|
||||
|
||||
To make local changes to isc-dhcp, simply patch and commit to the main
|
||||
branch (aka HEAD). Never make local changes on the vendor (ISC) branch.
|
||||
|
||||
All local changes should be submitted to the ISC for inclusion in the
|
||||
next vendor release.
|
||||
|
||||
[email protected]
|
||||
9-Feburary-1999
|
||||
@@ -1,288 +0,0 @@
|
||||
Internet Software Consortium
|
||||
Dynamic Host Configuration Protocol Distribution
|
||||
Version 2, Beta 1, Patchlevel 11
|
||||
February 8, 1998
|
||||
|
||||
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
|
||||
NetBSD, Linux, FreeBSD, BSD/OS, Ultrix, Digital Alpha OSF/1, and SunOS
|
||||
4.1.4. They can also be run usefully on Solaris as long as only one
|
||||
broadcast network interface is configured. They also runs on QNX 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.30 or previous kernel, the
|
||||
DHCP daemons will only be able to operate on machines with a single
|
||||
network 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 an
|
||||
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, unpack the compressed tar file using
|
||||
the tar utility and the gzip command - type something like:
|
||||
|
||||
zcat dhcp-2.0b1pl11.tar.gz |tar xvf -
|
||||
|
||||
Now, cd to the dhcp-2.0b1pl11 subdirectory that you've just created and
|
||||
configure the source tree by typing:
|
||||
|
||||
./configure
|
||||
|
||||
If the configure utility 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 warnings, it's not likely to be a problem - the DHCP
|
||||
server compiles completely warning-free on as many architectures
|
||||
as we can manage, but there are a few for which this is difficult.
|
||||
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.
|
||||
|
||||
Once you have successfully gotten the DHCP Distribution to build, you
|
||||
can install it by typing ``make install''. If you already have an old
|
||||
version of the DHCP Distribution installed, you may want to save it
|
||||
before typing ``make install''.
|
||||
|
||||
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. There are also two potential compilation/runtime
|
||||
problems for Linux 2.1/2.2: the "SO_ATTACH_FILTER undeclared" problem
|
||||
and the "protocol not configured" problem.
|
||||
|
||||
LINUX: SO_ATTACH_FILTER UNDECLARED
|
||||
|
||||
In addition, there is a minor issue that we will mention here because
|
||||
this release is so close on the heels of the Linux 2.2 release: there
|
||||
is a symlink in /usr/include that points at the linux asm headers. It
|
||||
appears to be not uncommon that this link won't be updated correctly,
|
||||
in which case you'll get the following error when you try to build:
|
||||
|
||||
lpf.c: In function `if_register_receive':
|
||||
lpf.c:152: `SO_ATTACH_FILTER' undeclared (first use this function)
|
||||
lpf.c:152: (Each undeclared identifier is reported only once
|
||||
lpf.c:152: for each function it appears in.)
|
||||
|
||||
The line numbers may be different, of course. If you see this
|
||||
header, your linux asm header link is probably bad, and you should
|
||||
make sure it's pointing to correct linux source directory.
|
||||
|
||||
LINUX: PROTOCOL NOT CONFIGURED
|
||||
|
||||
One additional Linux 2.1/2.2 issue: if you get the following message,
|
||||
it's because your kernel doesn't have the linux packetfilter
|
||||
configured:
|
||||
|
||||
Can't install packet filter program: Protocol not available
|
||||
exiting.
|
||||
|
||||
If this happens, you need to edit your linux kernel .config file, set
|
||||
CONFIG_FILTER=y, and rebuild your kernel. If the preceding sentence
|
||||
made no sense to you, ask your Linux vendor/guru for help - please
|
||||
don't ask us.
|
||||
|
||||
LINUX: 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.
|
||||
|
||||
LINUX: 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
|
||||
|
||||
|
||||
LINUX: 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 or later system
|
||||
headers installed *before* you build the DHCP Distribution.
|
||||
|
||||
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.
|
||||
|
||||
SOLARIS
|
||||
|
||||
One problem which has been observed and is not fixed in this patchlevel
|
||||
has to do with using DLPI on Solaris 2.6 machines, probably only on Intel,
|
||||
but possibly also on SPARC. The symptom of this problem is that you never
|
||||
receive any DHCP packets. If you are running Solaris 2.6, and you
|
||||
encounter this symptom, and you are running the DHCP server on a machine
|
||||
with a single broadcast network interface, you may wish to edit the
|
||||
includes/site.h file and uncomment the #define USE_SOCKETS line. Then
|
||||
type ``make clean; make''.
|
||||
|
||||
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 [email protected]
|
||||
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 [email protected] 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.
|
||||
|
||||
|
||||
@@ -1,447 +0,0 @@
|
||||
Internet Software Consortium
|
||||
Dynamic Host Configuration Protocol Distribution
|
||||
Version 2, Beta 1, Patchlevel 10
|
||||
February 8, 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 very conservative
|
||||
sites to run in production, but it is no longer recommended.
|
||||
|
||||
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 has been in a near feature freeze since January of 1998,
|
||||
has been in Beta test since then, and is planned for final release in
|
||||
mid-1999. It has a number of important features, and is the release
|
||||
that we would expect most sites to run. It is possible to run the
|
||||
Version 1 server with the Version 2 client at sites that want to be
|
||||
really conservative.
|
||||
|
||||
Version 3 of the ISC DHCP Distribution will add conditional behaviour,
|
||||
client classing, Dynamic DNS Support, DHCPv4 16-bit option codes,
|
||||
asynchronous DNS query resolution, DHCP Authentication, and possibly
|
||||
support for a DHCP Interserver Protocol and live querying of the DHCP
|
||||
database. Currently, only client classing and conditional behaviour
|
||||
have been implemented - the DNS code is waiting for an enhanced DNS
|
||||
resolver. The code has gone through a major internal restructuring
|
||||
which will help to support wider option codes, and possibly IPv6, as
|
||||
well as a more sensible memory allocation strategy. This release is
|
||||
running in producion at the ISC, but 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 10
|
||||
|
||||
- Update top-level Makefile so that it exits correctly on errors in
|
||||
submakes under bash/gnu make (dunno which is the culprit, and don't
|
||||
really care).
|
||||
|
||||
- Print a more helpful message if no free BPF devices are found.
|
||||
|
||||
- Add support for specifying that the server is or is not
|
||||
authoritative for a particular network segment.
|
||||
|
||||
- Fix two stupid typos in lpf.c.
|
||||
|
||||
- Print a more helpful message if we can't create an LPF socket or
|
||||
can't attach a filter to it.
|
||||
|
||||
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 9
|
||||
|
||||
- Correct the hopelessly outdated information about Linux at the top
|
||||
of the README - many apologies to the Linux people who have had to
|
||||
read that nonsense for the past couple of snapshots and have been
|
||||
confused or annoyed by it. I simply hadn't read it recently, and
|
||||
didn't realize how out-of-date it was.
|
||||
|
||||
- Print a message if the client finds no broadcast interfaces to
|
||||
configure.
|
||||
|
||||
- Add support for use-lease-addr-for-default-route flag in server, so
|
||||
that Windows machines can be made to ARP for all addresses.
|
||||
|
||||
- Update README file to mention new Linux gotchas.
|
||||
|
||||
- After finally understanding Brian Murrel's code (my fault, not his)
|
||||
to get interface names from /proc/net/dev on Linux, fix what I broke
|
||||
of his code and document it.
|
||||
|
||||
- Use sendto rather than send for SOCK_PACKET sockets, because they
|
||||
can't be connected, only bound. :'(
|
||||
|
||||
- Fix up SOCK_PACKET creation so that the kernel doesn't complain
|
||||
about it.
|
||||
|
||||
- Fix incorrect tests in linux client script:
|
||||
[ $relmajor == 2 ] -> [ $relmajor -eq 2 ]
|
||||
|
||||
- Make typedefs for u8, u16 and u32 types. These are Linux kernel
|
||||
internal data types which are unfortunately exposed in the linux
|
||||
packetfilter header file.
|
||||
|
||||
- Don't include <net/ethernet.h> in lpf.c - it defines things we're
|
||||
already correctly defining elsewhere, and doesn't define any useful
|
||||
new stuff.
|
||||
|
||||
- Finally fix client PREINIT bug that causes interfaces not specified
|
||||
on the command line to be preinitialized. If no interfaces are
|
||||
specified on the command line, all interfaces are still
|
||||
preinitialized.
|
||||
|
||||
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 8
|
||||
|
||||
- Fix socket API fallback setup code, which was causing Linux servers
|
||||
and clients to loop endlessly on select when run as daemons.
|
||||
|
||||
- Add support for Linux 2.2 version number (treated the same as Linux
|
||||
2.1, for now).
|
||||
|
||||
- Correct apparent error in DHCPREQUEST destination address handling
|
||||
when in INIT-REBOOT state.
|
||||
|
||||
- Do not set BROADCAST flag if we have a valid IP address.
|
||||
|
||||
- Remove hard-coded filenames and use system-specific manifest
|
||||
constants.
|
||||
|
||||
- Add entry and exit hooks to Linux dhclient-script (should be added
|
||||
to all operating systems once tested).
|
||||
|
||||
- Test for linux major and minor version so as to correctly invoke
|
||||
network configuration programs.
|
||||
|
||||
- Add support for Linux's gratuitous name change of bpf_insn structure
|
||||
(can't pollute precious Linux sources with the "Berkeley" word, I
|
||||
guess.
|
||||
|
||||
- Correct USE_BPF_{SEND,RECEIVE} ifdefs for if_reinitialize_*
|
||||
functions.
|
||||
|
||||
- Ensure that we have ifreq structure before initializing interface -
|
||||
if an interface was specified on the command line on Linux, this was
|
||||
not the case.
|
||||
|
||||
- Get rid of references to enstamp structure in lpf.c. Correctly
|
||||
declare and initialize sock_fprog structure (aka bpf_filter
|
||||
structure on non-Linux machines).
|
||||
|
||||
- Define ssize_t on Ultrix.
|
||||
|
||||
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 7
|
||||
|
||||
- Generalize FDDI support.
|
||||
|
||||
- Fix potential core dump in interface discovery code.
|
||||
|
||||
- Put explicit release versions on startup messages.
|
||||
|
||||
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 6
|
||||
|
||||
- Add support for Linux Packet Filter (thanks to Brian Murrell, Interlinx).
|
||||
|
||||
- Add support for FDDI hardware type.
|
||||
|
||||
- Fix a long-standing bug in DLPI support where the ethertype was
|
||||
being set incorrectly (thanks to Gong Wei, CCENet).
|
||||
|
||||
- Don't use DLPI RAW mode on Solaris.
|
||||
|
||||
- In the client, when a lease expires, the interface to which that
|
||||
lease is attached is unconfigured. On systems that use the socket
|
||||
API, the interface needs to then be reconfigured with the 0.0.0.0
|
||||
address so that it can be used to get a new address.
|
||||
|
||||
- Add fallback support for Linux. This fixes a problem with the
|
||||
relay agent when relaying over non-broadcast links, and may also fix
|
||||
some obscure problems with unicasting DHCPACKs in both the server and
|
||||
relay agent.
|
||||
|
||||
- When allocating leases, if the oldest lease is abandoned, try to
|
||||
find a younger-but-still-expired lease rather than reclaiming the
|
||||
abandoned lease.
|
||||
|
||||
- Add more documentation to README.
|
||||
|
||||
- The absence of the /etc/dhclient.conf file is no longer considered
|
||||
an error.
|
||||
|
||||
- The dhcp client's lease file name can be specified on the command
|
||||
line.
|
||||
|
||||
- The DHCP client should no longer zap interfaces that it has not been
|
||||
directed to configure.
|
||||
|
||||
- If a client starts up in the init-reboot state, the xid will be a
|
||||
"random" number rather than always being zero, as was previously the
|
||||
case.
|
||||
|
||||
- In addition to comparing transaction IDs, compare hardware addresses
|
||||
in response packets to verify that they are ours.
|
||||
|
||||
- Rewrite the client lease database after 20 leases have been written.
|
||||
|
||||
- Fix the exponential backoff code.
|
||||
|
||||
- Add a Y2k comment to indicate that something suspicious-looking is
|
||||
in fact _not_ a problem.
|
||||
|
||||
- Use mkstemp if possible.
|
||||
|
||||
- Add missing fi in various client scripts.
|
||||
|
||||
- Use "search" instead of "domain" in linux resolv.conf files.
|
||||
|
||||
- Specify a hop count in all route command on solaris.
|
||||
|
||||
- If an allocation fails, don't try to zero out the allocation buffer
|
||||
we didn't get.
|
||||
|
||||
- Support subnets that are subsets of other subnets - that is, for
|
||||
example, 10.0.1.0/24 and 10.0.0.0/16. This is useful in fairly
|
||||
obscure circumstances.
|
||||
|
||||
- Don't set the lease end time if it's already expired.
|
||||
|
||||
- Don't define INADDR_LOOPBACK on FreeBSD if it's already defined in a
|
||||
system header.
|
||||
|
||||
- Use the broadcast address in the relay agent if we are using the BSD
|
||||
socket API.
|
||||
|
||||
- Allow host declarations without names.
|
||||
|
||||
- Allow the server identifier option to be specified.
|
||||
|
||||
- Don't dump hostnames into the lease file if they contain
|
||||
non-printable characters.
|
||||
|
||||
- Copy the entire client hardware address buffer that the client sends
|
||||
to the output packet, not just the portion of it that's supposedly
|
||||
significant according to the hardware address length field. This
|
||||
is done for the benefit of certain Microsoft clients.
|
||||
|
||||
- Don't send a second ICMP echo request if we receive two DHCPDISCOVER
|
||||
messages in quick succession. This prevents a rather annoying
|
||||
timing race in configuring some Win95 clients.
|
||||
|
||||
- Fix up dhcp-options man page to make it more readable. Note that
|
||||
netbios-name-server is the same thing as WINS.
|
||||
|
||||
|
||||
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
@@ -1,190 +0,0 @@
|
||||
.\" 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 <[email protected]> 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 /etc/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.conf(5), dhclient.leases(5), dhclient(8)
|
||||
.SH AUTHOR
|
||||
.B dhclient-script(8)
|
||||
has been written for the Internet Software Consortium
|
||||
by Ted Lemon <[email protected]> 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.
|
||||
@@ -1,169 +0,0 @@
|
||||
.\" 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 <[email protected]> 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 -1
|
||||
]
|
||||
[
|
||||
.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.
|
||||
The
|
||||
.B -1
|
||||
flag cause dhclient to try once to get a lease. If it fails, dhclient exits.
|
||||
.PP
|
||||
.SH CONFIGURATION
|
||||
The syntax of the dhclient.conf(8) file is discussed seperately.
|
||||
.SH FILES
|
||||
.B /etc/dhclient.conf, /var/db/dhclient.leases, /var/run/dhclient.pid,
|
||||
.B /var/db/dhclient.leases~.
|
||||
.SH SEE ALSO
|
||||
dhclient.conf(5), dhclient.leases(5), dhclient-script(8)
|
||||
.SH AUTHOR
|
||||
.B dhclient(8)
|
||||
has been written for the Internet Software Consortium
|
||||
by Ted Lemon <[email protected]> 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
@@ -1,36 +0,0 @@
|
||||
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 "/sbin/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;
|
||||
}
|
||||
@@ -1,543 +0,0 @@
|
||||
.\" 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 <[email protected]> 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 "/sbin/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), dhclient(8), RFC2132,
|
||||
RFC2131
|
||||
.SH AUTHOR
|
||||
.B dhclient(8)
|
||||
was written by Ted Lemon <[email protected]>
|
||||
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.
|
||||
@@ -1,62 +0,0 @@
|
||||
.\" 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 <[email protected]> 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 /var/db/dhclient.leases
|
||||
.SH SEE ALSO
|
||||
dhcp-options(5), dhclient.conf(5), dhclient(8),
|
||||
RFC2132, RFC2131
|
||||
.SH AUTHOR
|
||||
.B dhclient(8)
|
||||
was written by Ted Lemon <[email protected]>
|
||||
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.
|
||||
@@ -1,175 +0,0 @@
|
||||
#!/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
|
||||
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
|
||||
@@ -1,330 +0,0 @@
|
||||
/* alloc.c
|
||||
|
||||
Memory allocation... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 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 <[email protected]> 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.2.1 1998/11/24 22:17:15 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);
|
||||
else
|
||||
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);
|
||||
}
|
||||
@@ -1,425 +0,0 @@
|
||||
/* bpf.c
|
||||
|
||||
BPF socket interface code, originally contributed by Archie Cobbs. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1998, 1999
|
||||
* 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 <[email protected]> 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.2.6 1999/02/09 04:46:59 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE) \
|
||||
|| defined (USE_LPF_RECEIVE)
|
||||
# if defined (USE_LPF_RECEIVE)
|
||||
# include <asm/types.h>
|
||||
# include <linux/filter.h>
|
||||
# define bpf_insn sock_filter /* Linux: dare to be gratuitously different. */
|
||||
# else
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/uio.h>
|
||||
|
||||
# include <net/bpf.h>
|
||||
# if defined (NEED_OSF_PFILT_HACKS)
|
||||
# include <net/pfilt.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include "includes/netinet/ip.h"
|
||||
#include "includes/netinet/udp.h"
|
||||
#include "includes/netinet/if_ether.h"
|
||||
#endif
|
||||
|
||||
/* 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. */
|
||||
|
||||
#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)
|
||||
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 {
|
||||
if (!b)
|
||||
error ("No bpf devices.%s%s%s",
|
||||
" Please read the README",
|
||||
" section for your operating",
|
||||
" system.");
|
||||
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 */
|
||||
|
||||
#if defined (USE_BPF_RECEIVE) || defined (USE_LPF_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 dhcp_bpf_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),
|
||||
};
|
||||
|
||||
int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
|
||||
#endif
|
||||
|
||||
#if defined (USE_BPF_RECEIVE)
|
||||
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 = dhcp_bpf_filter_len;
|
||||
p.bf_insns = dhcp_bpf_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 */
|
||||
dhcp_bpf_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];
|
||||
|
||||
if (!strcmp (interface -> name, "fallback"))
|
||||
return send_fallback (interface, packet, raw,
|
||||
len, from, to, hto);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int can_unicast_without_arp ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void maybe_setup_fallback ()
|
||||
{
|
||||
struct interface_info *fbi;
|
||||
fbi = setup_fallback ();
|
||||
if (fbi) {
|
||||
if_register_fallback (fbi);
|
||||
add_protocol ("fallback", fallback_interface -> wfdesc,
|
||||
fallback_discard, fallback_interface);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,560 +0,0 @@
|
||||
/* 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 <[email protected]> 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.2.3 1999/02/09 04:49:04 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;
|
||||
if (!strcasecmp (atom + 1, "uthoritative"))
|
||||
return AUTHORITATIVE;
|
||||
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;
|
||||
if (!strcasecmp (atom + 1, "ddi"))
|
||||
return FDDI;
|
||||
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;
|
||||
if (!strcasecmp (atom + 1, "ot"))
|
||||
return TOKEN_NOT;
|
||||
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 (!strncasecmp (atom + 1, "se", 2)) {
|
||||
if (!strcasecmp (atom + 3, "r-class"))
|
||||
return USER_CLASS;
|
||||
if (!strcasecmp (atom + 3, "-host-decl-names"))
|
||||
return USE_HOST_DECL_NAMES;
|
||||
if (!strcasecmp (atom + 3,
|
||||
"-lease-addr-for-default-route"))
|
||||
return USE_LEASE_ADDR_FOR_DEFAULT_ROUTE;
|
||||
break;
|
||||
}
|
||||
if (!strcasecmp (atom + 1, "id"))
|
||||
return UID;
|
||||
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;
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/* 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 <[email protected]> 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);
|
||||
}
|
||||
|
||||
@@ -1,581 +0,0 @@
|
||||
.\" dhcp-options.5
|
||||
.\"
|
||||
.\" 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 <[email protected]> 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
|
||||
.B option subnet-mask \fIip-address\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option time-offset \fIint32\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
The time-offset option specifies the offset of the client's subnet in
|
||||
seconds from Coordinated Universal Time (UTC).
|
||||
.RE
|
||||
.PP
|
||||
.B option routers \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option time-servers \fIip-address\fR [, \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBien116-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
];
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBdomain-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBlog-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBcookie-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBlpr-servers\fR \fIip-address \fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBimpress-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
The impress-server option specifies a list of Imagen Impress servers
|
||||
available to the client. Servers should be listed in order of
|
||||
preference.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBresource-location-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies a list of RFC 887 Resource Location
|
||||
servers available to the client. Servers should be listed in order
|
||||
of preference.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBhost-name\fR \fIstring\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBboot-size\fR \fIuint16\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the length in 512-octet blocks of the default
|
||||
boot image for the client.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBmerit-dump\fR \fIstring\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBdomain-name\fR \fIstring\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the domain name that client should use when
|
||||
resolving hostnames via the Domain Name System.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBswap-server\fR \fIip-address\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This specifies the IP address of the client's swap server.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBroot-path\fR \fIstring\fB;\fR\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBip-forwarding\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBnon-local-source-routing\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBpolicy-filter\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBmax-dgram-reassembly\fR \fIuint16\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the maximum size datagram that the client
|
||||
should be prepared to reassemble. The minimum value legal value is
|
||||
576.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBdefault-ip-ttl\fR \fIuint8;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the default time-to-live that the client should
|
||||
use on outgoing datagrams.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBpath-mtu-aging-timeout\fR \fIuint32\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the timeout (in seconds) to use when aging Path
|
||||
MTU values discovered by the mechanism defined in RFC 1191.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBpath-mtu-plateau-table\fR \fIuint16\fR [\fB,\fR \fIuint16\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBinterface-mtu\fR \fIuint16\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the MTU to use on this interface. The minimum
|
||||
legal value for the MTU is 68.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBall-subnets-local\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBbroadcast-address\fR \fIip-address\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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).
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBperform-mask-discovery\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBmask-supplier\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBrouter-discovery\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBrouter-solicitation-address\fR \fIip-address\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the address to which the client should transmit
|
||||
router solicitation requests.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBstatic-routes\fR \fIip-address ip-address\fR [\fB,\fR \fIip-address ip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBtrailer-encapsulation\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBarp-cache-timeout\fR \fIuint32\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the timeout in seconds for ARP cache entries.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBieee802-3-encapsulation\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBdefault-tcp-ttl\fR \fIuint8\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies the default TTL that the client should use when
|
||||
sending TCP segments. The minimum value is 1.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBtcp-keepalive-interval\fR \fIuint32\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBtcp-keepalive-garbage\fR \fIflag\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBnis-domain\fR \fIstring\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBnis-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies a list of IP addresses indicating NIS servers
|
||||
available to the client. Servers should be listed in order of
|
||||
preference.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBntp-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBnetbios-name-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
The NetBIOS name server (NBNS) option specifies a list of RFC
|
||||
1001/1002 NBNS name servers listed in order of preference. NetBIOS
|
||||
Name Service is currently more commonly referred to as WINS. WINS
|
||||
servers can be specified using the netbios-name-servers option.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBnetbios-dd-server\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
The NetBIOS datagram distribution server (NBDD) option specifies a
|
||||
list of RFC 1001/1002 NBDD servers listed in order of preference.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBnetbios-node-type\fR \fIuint8\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.PP
|
||||
Possible node types are:
|
||||
.PP
|
||||
.TP 5
|
||||
.I 1
|
||||
B-node: Broadcast - no WINS
|
||||
.TP
|
||||
.I 2
|
||||
P-node: Peer - WINS only.
|
||||
.TP
|
||||
.I 4
|
||||
M-node: Mixed - broadcast, then WINS
|
||||
.TP
|
||||
.I 8
|
||||
H-node: Hybrid - WINS, then broadcast
|
||||
.RE
|
||||
.PP
|
||||
.B option
|
||||
.B netbios-scope
|
||||
.I string\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBfont-servers\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.PP
|
||||
This option specifies a list of X Window System Font servers available
|
||||
to the client. Servers should be listed in order of preference.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBx-display-manager\fR \fIip-address\fR [\fB,\fR \fIip-address\fR...
|
||||
]\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
.B option \fBdhcp-client-identifier\fR \fIdata-string\fR\fB;\fR
|
||||
.RS 0.25i
|
||||
.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.
|
||||
.RE
|
||||
.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 <[email protected]>
|
||||
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.
|
||||
@@ -1,847 +0,0 @@
|
||||
/* dispatch.c
|
||||
|
||||
Network input dispatcher... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999 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 <[email protected]> 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.9 1999/02/05 20:23:50 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
|
||||
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 *));
|
||||
|
||||
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
|
||||
|
||||
/* 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. */
|
||||
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;
|
||||
|
||||
/* 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 defined (LINUX_SLASHPROC_DISCOVERY)
|
||||
/* On Linux, interfaces that don't have IP addresses don't show up
|
||||
in the SIOCGIFCONF syscall. We got away with this prior to
|
||||
Linux 2.1 because we would give each interface an IP address of
|
||||
0.0.0.0 before trying to boot, but that doesn't work after 2.1
|
||||
because we're using LPF, because we can't configure interfaces
|
||||
with IP addresses of 0.0.0.0 anymore (grumble). This only
|
||||
matters for the DHCP client, of course - the relay agent and
|
||||
server should only care about interfaces that are configured
|
||||
with IP addresses anyway.
|
||||
|
||||
The PROCDEV_DEVICE (/proc/net/dev) is a kernel-supplied file
|
||||
that, when read, prints a human readable network status. We
|
||||
extract the names of the network devices by skipping the first
|
||||
two lines (which are header) and then parsing off everything
|
||||
up to the colon in each subsequent line - these lines start
|
||||
with the interface name, then a colon, then a bunch of
|
||||
statistics. Yes, Virgina, this is a kludge, but you work
|
||||
with what you have. */
|
||||
|
||||
if (state == DISCOVER_UNCONFIGURED) {
|
||||
FILE *proc_dev;
|
||||
char buffer [256];
|
||||
struct ifreq *tif;
|
||||
int skip = 2;
|
||||
|
||||
proc_dev = fopen (PROCDEV_DEVICE, "r");
|
||||
if (!proc_dev)
|
||||
error ("%s: %m", PROCDEV_DEVICE);
|
||||
|
||||
while (fgets (buffer, sizeof buffer, proc_dev)) {
|
||||
char *name = buffer;
|
||||
char *sep;
|
||||
|
||||
/* Skip the first two blocks, which are header
|
||||
lines. */
|
||||
if (skip) {
|
||||
--skip;
|
||||
continue;
|
||||
}
|
||||
|
||||
sep = strrchr (buffer, ':');
|
||||
if (sep)
|
||||
*sep = '\0';
|
||||
while (*name == ' ')
|
||||
name++;
|
||||
|
||||
/* See if we've seen an interface that matches
|
||||
this one. */
|
||||
for (tmp = interfaces; tmp; tmp = tmp -> next)
|
||||
if (!strcmp (tmp -> name, name))
|
||||
break;
|
||||
|
||||
/* If we found one, and it already has an ifreq
|
||||
structure, nothing more to do.. */
|
||||
if (tmp && tmp -> ifp)
|
||||
continue;
|
||||
|
||||
/* Make up an ifreq structure. */
|
||||
tif = (struct ifreq *)malloc (sizeof (struct ifreq));
|
||||
if (!tif)
|
||||
error ("no space to remember ifp.");
|
||||
memset (tif, 0, sizeof (struct ifreq));
|
||||
strcpy (tif -> ifr_name, name);
|
||||
|
||||
/* Now, if we just needed the ifreq structure, hook
|
||||
it in and move on. */
|
||||
if (tmp) {
|
||||
tmp -> ifp = tif;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Otherwise, allocate one. */
|
||||
tmp = ((struct interface_info *)
|
||||
dmalloc (sizeof *tmp, "discover_interfaces"));
|
||||
if (!tmp)
|
||||
error ("Insufficient memory to %s %s",
|
||||
"record interface", name);
|
||||
memset (tmp, 0, sizeof *tmp);
|
||||
strcpy (tmp -> name, name);
|
||||
|
||||
tmp -> ifp = tif;
|
||||
tmp -> flags = ir;
|
||||
tmp -> next = interfaces;
|
||||
interfaces = tmp;
|
||||
}
|
||||
fclose (proc_dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now cycle through all the interfaces we found, looking for
|
||||
hardware addresses. */
|
||||
#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
|
||||
for (tmp = interfaces; tmp; tmp = tmp -> next) {
|
||||
struct ifreq ifr;
|
||||
struct sockaddr sa;
|
||||
int b, sk;
|
||||
|
||||
/* Read the hardware address from this interface. */
|
||||
ifr = *tmp -> ifp;
|
||||
if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
#ifndef ARPHRD_FDDI
|
||||
# define ARPHRD_FDDI HTYPE_FDDI
|
||||
#endif
|
||||
case ARPHRD_FDDI:
|
||||
tmp -> hw_address.hlen = 16;
|
||||
tmp -> hw_address.htype = HTYPE_FDDI; /* XXX */
|
||||
memcpy (tmp -> hw_address.haddr, sa.sa_data, 16);
|
||||
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) */
|
||||
|
||||
/* 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);
|
||||
|
||||
maybe_setup_fallback ();
|
||||
}
|
||||
|
||||
struct interface_info *setup_fallback ()
|
||||
{
|
||||
fallback_interface =
|
||||
((struct interface_info *)
|
||||
dmalloc (sizeof *fallback_interface, "discover_interfaces"));
|
||||
if (!fallback_interface)
|
||||
error ("Insufficient memory to record fallback interface.");
|
||||
memset (fallback_interface, 0, sizeof *fallback_interface);
|
||||
strcpy (fallback_interface -> name, "fallback");
|
||||
fallback_interface -> shared_network =
|
||||
new_shared_network ("parse_statement");
|
||||
if (!fallback_interface -> shared_network)
|
||||
error ("No memory for shared subnet");
|
||||
memset (fallback_interface -> shared_network, 0,
|
||||
sizeof (struct shared_network));
|
||||
fallback_interface -> shared_network -> name = "fallback-net";
|
||||
return fallback_interface;
|
||||
}
|
||||
|
||||
void reinitialize_interfaces ()
|
||||
{
|
||||
struct interface_info *ip;
|
||||
|
||||
for (ip = interfaces; ip; ip = ip -> next) {
|
||||
if_reinitialize_receive (ip);
|
||||
if_reinitialize_send (ip);
|
||||
}
|
||||
|
||||
if (fallback_interface)
|
||||
if_reinitialize_send (fallback_interface);
|
||||
|
||||
interfaces_invalidated = 1;
|
||||
}
|
||||
|
||||
#ifdef USE_POLL
|
||||
/* Wait for packets to come in using poll(). When a packet comes in,
|
||||
call receive_packet to receive the packet and possibly strip hardware
|
||||
addressing information from it, and then call through the
|
||||
bootp_packet_handler hook to try to do something with it. */
|
||||
|
||||
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 through the
|
||||
bootp_packet_handler hook 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 */
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,391 +0,0 @@
|
||||
/* 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 */
|
||||
@@ -1,175 +0,0 @@
|
||||
/* 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 <[email protected]> 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;
|
||||
}
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
/* 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 <[email protected]> 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);
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
/* 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 <[email protected]> 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;
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/* $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
|
||||
@@ -1,287 +0,0 @@
|
||||
/* lpf.c
|
||||
|
||||
Linux packet filter code, contributed by Brian Murrel at Interlinx
|
||||
Support Services in Vancouver, B.C. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1998, 1999
|
||||
* 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 <[email protected]> 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: lpf.c,v 1.1.2.4 1999/02/09 04:51:05 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#include "dhcpd.h"
|
||||
#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/if_ether.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_LPF_SEND
|
||||
void if_reinitialize_send (info)
|
||||
struct interface_info *info;
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LPF_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_lpf (info)
|
||||
struct interface_info *info;
|
||||
{
|
||||
int sock;
|
||||
char filename[50];
|
||||
int b;
|
||||
struct sockaddr sa;
|
||||
|
||||
/* Make an LPF socket. */
|
||||
if ((sock = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
|
||||
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
error ("socket: %m - make sure %s %s!",
|
||||
"CONFIG_PACKET and CONFIG_FILTER are defined",
|
||||
"in your kernel configuration");
|
||||
error("Open a socket for LPF: %m");
|
||||
}
|
||||
|
||||
/* Bind to the interface name */
|
||||
memset (&sa, 0, sizeof sa);
|
||||
sa.sa_family = AF_PACKET;
|
||||
strncpy (sa.sa_data, (const char *)info -> ifp, sizeof sa.sa_data);
|
||||
if (bind (sock, &sa, sizeof sa)) {
|
||||
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
error ("socket: %m - make sure %s %s!",
|
||||
"CONFIG_PACKET and CONFIG_FILTER are defined",
|
||||
"in your kernel configuration");
|
||||
error("Bind socket to interface: %m");
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
#endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
|
||||
|
||||
#ifdef USE_LPF_SEND
|
||||
void if_register_send (info)
|
||||
struct interface_info *info;
|
||||
{
|
||||
/* If we're using the lpf API for sending and receiving,
|
||||
we don't need to register this interface twice. */
|
||||
#ifndef USE_LPF_RECEIVE
|
||||
info -> wfdesc = if_register_lpf (info, interface);
|
||||
#else
|
||||
info -> wfdesc = info -> rfdesc;
|
||||
#endif
|
||||
if (!quiet_interface_discovery)
|
||||
note ("Sending on LPF/%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_LPF_SEND */
|
||||
|
||||
#ifdef USE_LPF_RECEIVE
|
||||
/* Defined in bpf.c. We can't extern these in dhcpd.h without pulling
|
||||
in bpf includes... */
|
||||
extern struct sock_filter dhcp_bpf_filter [];
|
||||
extern int dhcp_bpf_filter_len;
|
||||
|
||||
void if_register_receive (info)
|
||||
struct interface_info *info;
|
||||
{
|
||||
struct sock_fprog p;
|
||||
|
||||
/* Open a LPF device and hang it on this interface... */
|
||||
info -> rfdesc = if_register_lpf (info);
|
||||
|
||||
/* Set up the bpf filter program structure. This is defined in
|
||||
bpf.c */
|
||||
p.len = dhcp_bpf_filter_len;
|
||||
p.filter = dhcp_bpf_filter;
|
||||
|
||||
/* Patch the server port into the LPF program...
|
||||
XXX changes to filter program may require changes
|
||||
to the insn number(s) used below! XXX */
|
||||
dhcp_bpf_filter [8].k = ntohs (local_port);
|
||||
|
||||
if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
|
||||
sizeof p) < 0) {
|
||||
if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
|
||||
errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
|
||||
errno == EAFNOSUPPORT)
|
||||
error ("socket: %m - make sure %s %s!",
|
||||
"CONFIG_PACKET and CONFIG_FILTER are defined",
|
||||
"in your kernel configuration");
|
||||
error ("Can't install packet filter program: %m");
|
||||
}
|
||||
if (!quiet_interface_discovery)
|
||||
note ("Listening on LPF/%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_LPF_RECEIVE */
|
||||
|
||||
#ifdef USE_LPF_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 [1500];
|
||||
struct sockaddr sa;
|
||||
|
||||
if (!strcmp (interface -> name, "fallback"))
|
||||
return send_fallback (interface, packet, raw,
|
||||
len, from, to, hto);
|
||||
|
||||
/* 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);
|
||||
memcpy (buf + bufp, raw, len);
|
||||
|
||||
/* For some reason, SOCK_PACKET sockets can't be connected,
|
||||
so we have to do a sentdo every time. */
|
||||
memset (&sa, 0, sizeof sa);
|
||||
sa.sa_family = AF_PACKET;
|
||||
strncpy (sa.sa_data,
|
||||
(const char *)interface -> ifp, sizeof sa.sa_data);
|
||||
|
||||
return sendto (interface -> wfdesc, buf, bufp + len, 0,
|
||||
&sa, sizeof sa);
|
||||
}
|
||||
#endif /* USE_LPF_SEND */
|
||||
|
||||
#ifdef USE_LPF_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];
|
||||
int bufix = 0;
|
||||
|
||||
length = read (interface -> rfdesc, ibuf, sizeof ibuf);
|
||||
if (length <= 0)
|
||||
return length;
|
||||
|
||||
bufix = 0;
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int can_unicast_without_arp ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void maybe_setup_fallback ()
|
||||
{
|
||||
struct interface_info *fbi;
|
||||
fbi = setup_fallback ();
|
||||
if (fbi) {
|
||||
if_register_fallback (fbi);
|
||||
add_protocol ("fallback", fallback_interface -> wfdesc,
|
||||
fallback_discard, fallback_interface);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,941 +0,0 @@
|
||||
/* 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 <[email protected]> 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.3 1998/11/24 22:32:43 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;
|
||||
}
|
||||
|
||||
int subnet_inner_than (subnet, scan, warnp)
|
||||
struct subnet *subnet, *scan;
|
||||
int warnp;
|
||||
{
|
||||
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));
|
||||
if (warnp)
|
||||
warn ("%ssubnet %s/%d conflicts with subnet %s/%d",
|
||||
"Warning: ", n1buf, 32 - i,
|
||||
piaddr (scan -> net), 32 - j);
|
||||
if (i < j)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Enter a new subnet into the subnet list. */
|
||||
|
||||
void enter_subnet (subnet)
|
||||
struct subnet *subnet;
|
||||
{
|
||||
struct subnet *scan, *prev = (struct subnet *)0;
|
||||
|
||||
/* Check for duplicates... */
|
||||
for (scan = subnets; scan; scan = scan -> next_subnet) {
|
||||
/* When we find a conflict, make sure that the
|
||||
subnet with the narrowest subnet mask comes
|
||||
first. */
|
||||
if (subnet_inner_than (subnet, scan, 1)) {
|
||||
if (prev) {
|
||||
prev -> next_subnet = subnet;
|
||||
} else
|
||||
subnets = subnet;
|
||||
subnet -> next_subnet = scan;
|
||||
return;
|
||||
}
|
||||
prev = scan;
|
||||
}
|
||||
|
||||
/* XXX use the BSD radix tree code instead of a linked list. */
|
||||
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;
|
||||
if (lt.ends > cur_time) {
|
||||
lt.ends = cur_time;
|
||||
supersede_lease (lease, <, 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, <, 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;
|
||||
|
||||
note ("Subnets:");
|
||||
for (n = subnets; n; n = n -> next_subnet) {
|
||||
debug (" Subnet %s", piaddr (n -> net));
|
||||
debug (" netmask %s",
|
||||
piaddr (n -> netmask));
|
||||
}
|
||||
note ("Shared networks:");
|
||||
for (s = shared_networks; s; s = s -> next) {
|
||||
note (" %s", s -> name);
|
||||
for (l = s -> leases; l; l = l -> next) {
|
||||
print_lease (l);
|
||||
}
|
||||
if (s -> last_lease) {
|
||||
debug (" Last Lease:");
|
||||
print_lease (s -> last_lease);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,367 +0,0 @@
|
||||
/* 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 <[email protected]> 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.2.1 1998/12/20 18:27:44 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 *)𝔦
|
||||
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;
|
||||
|
||||
if (!strcmp (interface -> name, "fallback"))
|
||||
return send_fallback (interface, packet, raw,
|
||||
len, from, to, hto);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int can_unicast_without_arp ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void maybe_setup_fallback ()
|
||||
{
|
||||
struct interface_info *fbi;
|
||||
fbi = setup_fallback ();
|
||||
if (fbi) {
|
||||
if_register_fallback (fbi);
|
||||
add_protocol ("fallback", fallback_interface -> wfdesc,
|
||||
fallback_discard, fallback_interface);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,609 +0,0 @@
|
||||
/* 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 <[email protected]> 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);
|
||||
}
|
||||
|
||||
@@ -1,311 +0,0 @@
|
||||
/* 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 <[email protected]> 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 */
|
||||
@@ -1,649 +0,0 @@
|
||||
/* 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 <[email protected]> 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.3 1998/12/22 22:43:22 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;
|
||||
case FDDI:
|
||||
hardware -> htype = HTYPE_FDDI;
|
||||
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);
|
||||
if (hlen < sizeof hardware -> haddr)
|
||||
memset (&hardware -> haddr [hlen], 0,
|
||||
(sizeof hardware -> haddr) - 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;
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/* 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 <[email protected]> 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.2 1998/11/24 22:39:35 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/* 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 <[email protected]> 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 */
|
||||
@@ -1,280 +0,0 @@
|
||||
/* socket.c
|
||||
|
||||
BSD socket interface code... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999
|
||||
* 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 <[email protected]> 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 ([email protected]).
|
||||
* 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.6 1999/02/03 19:46:04 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 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;
|
||||
|
||||
#if !defined (SO_BINDTODEVICE) && !defined (USE_FALLBACK)
|
||||
/* 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");
|
||||
|
||||
#if defined (SO_BINDTODEVICE)
|
||||
/* Bind this socket to this interface. */
|
||||
if (info -> ifp &&
|
||||
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_SEND
|
||||
/* 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_SEND */
|
||||
|
||||
#if defined (USE_SOCKET_SEND) && !defined (USE_SOCKET_FALLBACK)
|
||||
int can_unicast_without_arp ()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we have SO_BINDTODEVICE, set up a fallback interface; otherwise,
|
||||
do not. */
|
||||
|
||||
void maybe_setup_fallback ()
|
||||
{
|
||||
#if defined (SO_BINDTODEVICE)
|
||||
struct interface_info *fbi;
|
||||
fbi = setup_fallback ();
|
||||
if (fbi) {
|
||||
fbi -> wfdesc = if_register_socket (fbi);
|
||||
add_protocol ("fallback",
|
||||
fbi -> wfdesc, fallback_discard, fbi);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_SOCKET_SEND && !USE_SOCKET_FALLBACK */
|
||||
@@ -1,692 +0,0 @@
|
||||
/* 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 <[email protected]> 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.3 1998/12/22 22:45:44 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", "X", &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",
|
||||
"fddi",
|
||||
"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);
|
||||
}
|
||||
@@ -1,412 +0,0 @@
|
||||
/* 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;
|
||||
}
|
||||
@@ -1,318 +0,0 @@
|
||||
/* 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.2.1 1998/12/20 18:29:48 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, ¶m) < 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];
|
||||
|
||||
if (!strcmp (interface -> name, "fallback"))
|
||||
return send_fallback (interface, packet, raw,
|
||||
len, from, to, hto);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
int can_unicast_without_arp ()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void maybe_setup_fallback ()
|
||||
{
|
||||
struct interface_info *fbi;
|
||||
fbi = setup_fallback ();
|
||||
if (fbi) {
|
||||
if_register_fallback (fbi);
|
||||
add_protocol ("fallback", fallback_interface -> wfdesc,
|
||||
fallback_discard, fallback_interface);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,237 +0,0 @@
|
||||
/*
|
||||
* ++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_ */
|
||||
@@ -1,57 +0,0 @@
|
||||
/* 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__ */
|
||||
@@ -1,93 +0,0 @@
|
||||
/* freebsd.h
|
||||
|
||||
System dependencies for FreeBSD... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, 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.
|
||||
*/
|
||||
|
||||
#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>
|
||||
#include <net/if_arp.h>
|
||||
#if !defined (INADDR_LOOPBACK)
|
||||
# define INADDR_LOOPBACK ((u_int32_t)0x7f000001)
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
@@ -1,168 +0,0 @@
|
||||
/* 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... */
|
||||
#define HTYPE_FDDI 8 /* FDDI... */
|
||||
|
||||
/* 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
|
||||
@@ -1,1000 +0,0 @@
|
||||
/* dhcpd.h
|
||||
|
||||
Definitions for dhcpd... */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999
|
||||
* 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 [DHCP_FILE_LEN];
|
||||
char *server_name;
|
||||
|
||||
struct iaddr from;
|
||||
|
||||
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;
|
||||
int use_lease_addr_for_default_route;
|
||||
int authoritative;
|
||||
|
||||
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;
|
||||
|
||||
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 *));
|
||||
int subnet_inner_than PROTO ((struct subnet *, struct subnet *, int));
|
||||
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 *));
|
||||
#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
|
||||
#if defined (USE_SOCKET_FALLBACK)
|
||||
void fallback_discard PROTO ((struct protocol *));
|
||||
#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)
|
||||
int can_unicast_without_arp PROTO ((void));
|
||||
void maybe_setup_fallback PROTO ((void));
|
||||
#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)
|
||||
int can_unicast_without_arp PROTO ((void));
|
||||
void maybe_setup_fallback PROTO ((void));
|
||||
#endif
|
||||
|
||||
/* lpf.c */
|
||||
#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
|
||||
int if_register_lpf PROTO ( (struct interface_info *));
|
||||
#endif
|
||||
#ifdef USE_LPF_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_LPF_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_LPF_SEND)
|
||||
int can_unicast_without_arp PROTO ((void));
|
||||
void maybe_setup_fallback PROTO ((void));
|
||||
#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_NIT_SEND)
|
||||
int can_unicast_without_arp PROTO ((void));
|
||||
void maybe_setup_fallback PROTO ((void));
|
||||
#endif
|
||||
|
||||
#ifdef USE_DLPI_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_DLPI_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_DLPI_SEND)
|
||||
int can_unicast_without_arp PROTO ((void));
|
||||
void maybe_setup_fallback PROTO ((void));
|
||||
#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 *));
|
||||
int can_unicast_without_arp PROTO ((void));
|
||||
void maybe_setup_fallback PROTO ((void));
|
||||
#endif
|
||||
|
||||
/* dispatch.c */
|
||||
extern struct interface_info *interfaces,
|
||||
*dummy_interfaces, *fallback_interface;
|
||||
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));
|
||||
struct interface_info *setup_fallback PROTO ((void));
|
||||
void reinitialize_interfaces PROTO ((void));
|
||||
void dispatch PROTO ((void));
|
||||
int locate_network PROTO ((struct packet *));
|
||||
void got_one PROTO ((struct protocol *));
|
||||
void add_timeout PROTO ((TIME, void (*) PROTO ((void *)), void *));
|
||||
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 *, int));
|
||||
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));
|
||||
@@ -1,135 +0,0 @@
|
||||
/* dhctoken.h
|
||||
|
||||
Tokens for config file lexer and parser. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995, 1996, 1997, 1998, 1999
|
||||
* 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 FDDI 331
|
||||
#define USE_LEASE_ADDR_FOR_DEFAULT_ROUTE 332
|
||||
#define AUTHORITATIVE 333
|
||||
#define TOKEN_NOT 334
|
||||
|
||||
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
|
||||
(x) != STRING && \
|
||||
(x) != NUMBER && \
|
||||
(x) != EOF)
|
||||
@@ -1,56 +0,0 @@
|
||||
/* 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];
|
||||
};
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/* 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;
|
||||
};
|
||||
@@ -1,74 +0,0 @@
|
||||
/* $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)
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/* $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 */
|
||||
@@ -1,182 +0,0 @@
|
||||
/* $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
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/* $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 */
|
||||
};
|
||||
@@ -1,228 +0,0 @@
|
||||
/* 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_LPF) && \
|
||||
!defined (USE_LPF_SEND) && \
|
||||
!defined (USE_LPF_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_LPF
|
||||
# define USE_LPF_SEND
|
||||
# define USE_LPF_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) || defined (USE_LPF_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) || defined (USE_LPF_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) || defined (USE_LPF_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
|
||||
@@ -1,100 +0,0 @@
|
||||
/* 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 */
|
||||
@@ -1,52 +0,0 @@
|
||||
/* 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
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
/* 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;
|
||||
};
|
||||
@@ -24,7 +24,7 @@ static const char copyright[] =
|
||||
"@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
static const char rcsid[] =
|
||||
"@(#)$Header: /home/ncvs/src/contrib/traceroute/traceroute.c,v 1.5 1996/10/08 19:16:24 sef Exp $ (LBL)";
|
||||
"@(#)$Header: /home/ncvs/src/contrib/traceroute/traceroute.c,v 1.7 1999/02/15 08:11:44 des Exp $ (LBL)";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -732,6 +732,8 @@ wait_for_reply(register int sock, register struct sockaddr_in *fromp,
|
||||
wait.tv_sec = tp->tv_sec + waittime;
|
||||
wait.tv_usec = tp->tv_usec;
|
||||
(void)gettimeofday(&now, &tz);
|
||||
if (wait.tv_sec < now.tv_sec + 1)
|
||||
wait.tv_sec = now.tv_sec + 1;
|
||||
tvsub(&wait, &now);
|
||||
|
||||
if (select(sock + 1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
# $Id$
|
||||
#
|
||||
# This file is required by the ISC DHCP client.
|
||||
# See ``man 5 dhclient.conf'' for details.
|
||||
#
|
||||
# In most cases an empty file is suffient for most people as the
|
||||
# defaults are usually fine.
|
||||
#
|
||||
@@ -1,100 +0,0 @@
|
||||
#
|
||||
# /etc/rc.diskless - general BOOTP startup
|
||||
#
|
||||
# BOOTP has mounted / for us. Assume a read-only mount. We must then
|
||||
# - figure out where the NFS mount is coming from
|
||||
# - figure out our IP by querying the interface
|
||||
# - retarget /conf/ME softlink to proper configuration script directory
|
||||
#
|
||||
# It is expected that /etc/fstab and /etc/rc.conf.local will be
|
||||
# set by the system operator on the server to be softlinks to
|
||||
# /conf/ME/fstab and /conf/ME/rc.conf.local. The system operator may
|
||||
# choose to retarget other files as well. The server itself boots
|
||||
# properly with its default /conf/ME softlink pointing to
|
||||
# /conf/server.host.name.
|
||||
#
|
||||
# During a diskless boot, we retarget the /conf/ME softlink to point
|
||||
# to /conf/DISKLESS.CLIENT.IP.ADDRESS. Thus, various system config
|
||||
# files that are softlinks through /conf/ME also get retargeted.
|
||||
#
|
||||
# SEE SAMPLE FILES IN /usr/share/examples/diskless.
|
||||
|
||||
# chkerr:
|
||||
#
|
||||
# Routine to check for error
|
||||
#
|
||||
# checks error code and drops into shell on failure.
|
||||
# if shell exits, terminates script as well as /etc/rc.
|
||||
|
||||
chkerr() {
|
||||
if [ $1 != 0 ]; then
|
||||
echo "$2 failed: dropping into /bin/sh"
|
||||
/bin/sh
|
||||
# RESUME
|
||||
fi
|
||||
}
|
||||
|
||||
# DEBUGGING
|
||||
#
|
||||
set -v
|
||||
|
||||
# Figure out where the root mount is coming from, synthesize a mount
|
||||
# for /usr and mount it.
|
||||
#
|
||||
# e.g. nfs_root might wind up as "A.B.C.D:/"
|
||||
#
|
||||
# NOTE! the /usr mount is only temporary so we can access commands necessary
|
||||
# to retarget /conf/ME. The actual /usr mount should be part of the
|
||||
# retargeted /etc/fstab. See instructions in /usr/share/examples/diskless.
|
||||
#
|
||||
set `/bin/df /`
|
||||
nfs_root=$8
|
||||
mount_nfs -o ro ${nfs_root}/usr /usr
|
||||
|
||||
chkerr $? "mount of /usr"
|
||||
|
||||
# Figure out our interface and IP.
|
||||
#
|
||||
|
||||
bootp_ifc=`route -n get default | fgrep interface | awk '{ print $2; }'`
|
||||
bootp_ipa=`ifconfig $bootp_ifc | fgrep inet | head -1 | awk '{ print $2; }'`
|
||||
|
||||
echo "Interface $bootp_ifc IP-Address $bootp_ipa"
|
||||
|
||||
umount /usr
|
||||
|
||||
# retarget /conf/ME
|
||||
#
|
||||
# MFS's background process takes a bit to startup. Various config files
|
||||
# on server should be softlinks through /conf/ME. The server's own /conf/ME
|
||||
# points to the server's version of the files.
|
||||
#
|
||||
# We retarget /conf/ME using a -o union mount. This allows
|
||||
# us to 'mkdir' over whatever was there previously.
|
||||
#
|
||||
# WARNING! null mounts cannot handle mmap, and since many programs
|
||||
# use mmap (such as 'cp'), we have to copy.
|
||||
|
||||
mount_mfs -s 256 -T qp120at -o union dummy /conf
|
||||
chkerr $? "MFS mount on /conf"
|
||||
|
||||
mkdir /conf/ME
|
||||
cp -Rp /conf/$bootp_ipa/* /conf/ME
|
||||
|
||||
# retarget the kernel
|
||||
#
|
||||
|
||||
sysctl -w kern.bootfile=/conf/ME/kernel
|
||||
|
||||
# Tell /etc/rc to run the specified script after
|
||||
# it does its mounts but before it does anything
|
||||
# else.
|
||||
#
|
||||
# This script is responsible for setting up the
|
||||
# diskless mount environment. This can be
|
||||
# overriden by /conf/ME/rc.conf.local if, for
|
||||
# example, you do not want to run the standard
|
||||
# system /etc/rc.diskless2
|
||||
|
||||
diskless_mount="/etc/rc.diskless2"
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# rc.diskless2
|
||||
#
|
||||
|
||||
# If there is a global system configuration file, suck it in.
|
||||
#
|
||||
if [ -f /etc/defaults/rc.conf ]; then
|
||||
. /etc/defaults/rc.conf
|
||||
elif [ -f /etc/rc.conf ]; then
|
||||
. /etc/rc.conf
|
||||
fi
|
||||
|
||||
mount_mfs -s ${var_run_sectors:=2048} -T qp120at dummy /var/run
|
||||
mount_mfs -s ${var_db_sectors:=16384} -T qp120at dummy /var/db
|
||||
mount_mfs -s ${var_tmp_sectors:=65536} -T qp120at dummy /var/tmp
|
||||
mount_mfs -s ${var_spool_sectors:=65536} -T qp120at dummy /var/spool
|
||||
chmod 755 /var/run
|
||||
chmod 755 /var/db
|
||||
chmod 755 /var/spool
|
||||
chmod 1777 /var/tmp
|
||||
|
||||
if [ ! -h /tmp -a ! -h /var/tmp ]; then
|
||||
mount_null /var/tmp /tmp
|
||||
fi
|
||||
|
||||
mkdir /var/spool/mqueue
|
||||
mkdir /var/spool/lpd
|
||||
mkdir /var/spool/output
|
||||
mkdir /var/spool/output/lpd
|
||||
chown -R root.daemon /var/spool/output
|
||||
chgrp daemon /var/spool/lpd
|
||||
|
||||
( cd /; find -x dev | cpio -o -H newc ) > /tmp/dev.tmp
|
||||
mount_mfs -s 4096 -i 512 -T qp120at dummy /dev
|
||||
( cd /; cpio -i -H newc -d < /tmp/dev.tmp )
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
*** hsuser.texinfo Fri May 1 23:48:48 1998
|
||||
--- inc-hist.texi Mon Jun 30 22:57:58 1997
|
||||
***************
|
||||
*** 34,42 ****
|
||||
@end ifset
|
||||
@ifclear BashFeatures
|
||||
This chapter describes how to use the GNU History Library interactively,
|
||||
! from a user's standpoint. It should be considered a user's guide. For
|
||||
! information on using the GNU History Library in your own programs,
|
||||
! @pxref{Programming with GNU History}.
|
||||
@end ifclear
|
||||
|
||||
@ifset BashFeatures
|
||||
--- 34,43 ----
|
||||
@end ifset
|
||||
@ifclear BashFeatures
|
||||
This chapter describes how to use the GNU History Library interactively,
|
||||
! from a user's standpoint.
|
||||
! @c It should be considered a user's guide. For
|
||||
! @c information on using the GNU History Library in your own programs,
|
||||
! @c @pxref{Programming with GNU History}.
|
||||
@end ifclear
|
||||
|
||||
@ifset BashFeatures
|
||||
@@ -1,385 +0,0 @@
|
||||
.\" Copyright (c) 1991 Free Software Foundation
|
||||
.\" See section COPYING for conditions for redistribution
|
||||
.\" $Id: gdb.1,v 1.3 1991/12/13 22:22:58 pesch Exp $
|
||||
.TH gdb 1 "4nov1991" "GNU Tools" "GNU Tools"
|
||||
.SH NAME
|
||||
gdb \- The GNU Debugger
|
||||
.SH SYNOPSIS
|
||||
.na
|
||||
.TP
|
||||
.B gdb
|
||||
.RB "[\|" \-help "\|]"
|
||||
.RB "[\|" \-nx "\|]"
|
||||
.RB "[\|" \-q "\|]"
|
||||
.RB "[\|" \-batch "\|]"
|
||||
.RB "[\|" \-cd=\c
|
||||
.I dir\c
|
||||
\|]
|
||||
.RB "[\|" \-f "\|]"
|
||||
.RB "[\|" \-k "\|]"
|
||||
.RB "[\|" \-wcore "\|]"
|
||||
.RB "[\|" "\-b\ "\c
|
||||
.IR bps "\|]"
|
||||
.RB "[\|" "\-tty="\c
|
||||
.IR dev "\|]"
|
||||
.RB "[\|" "\-s "\c
|
||||
.I symfile\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-e "\c
|
||||
.I prog\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-se "\c
|
||||
.I prog\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-c "\c
|
||||
.I core\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-x "\c
|
||||
.I cmds\c
|
||||
\&\|]
|
||||
.RB "[\|" "\-d "\c
|
||||
.I dir\c
|
||||
\&\|]
|
||||
.RB "[\|" \c
|
||||
.I prog\c
|
||||
.RB "[\|" \c
|
||||
.IR core \||\| procID\c
|
||||
\&\|]\&\|]
|
||||
.ad b
|
||||
.SH DESCRIPTION
|
||||
The purpose of a debugger such as GDB is to allow you to see what is
|
||||
going on ``inside'' another program while it executes\(em\&or what another
|
||||
program was doing at the moment it crashed.
|
||||
|
||||
GDB can do four main kinds of things (plus other things in support of
|
||||
these) to help you catch bugs in the act:
|
||||
|
||||
.TP
|
||||
\ \ \ \(bu
|
||||
Start your program, specifying anything that might affect its behavior.
|
||||
|
||||
.TP
|
||||
\ \ \ \(bu
|
||||
Make your program stop on specified conditions.
|
||||
|
||||
.TP
|
||||
\ \ \ \(bu
|
||||
Examine what has happened, when your program has stopped.
|
||||
|
||||
.TP
|
||||
\ \ \ \(bu
|
||||
Change things in your program, so you can experiment with correcting the
|
||||
effects of one bug and go on to learn about another.
|
||||
.PP
|
||||
|
||||
You can use GDB to debug programs written in C, C++, and Modula-2.
|
||||
Fortran support will be added when a GNU Fortran compiler is ready.
|
||||
|
||||
GDB is invoked with the shell command \c
|
||||
.B gdb\c
|
||||
\&. Once started, it reads
|
||||
commands from the terminal until you tell it to exit with the GDB
|
||||
command \c
|
||||
.B quit\c
|
||||
\&. You can get online help from \c
|
||||
.B gdb\c
|
||||
\& itself
|
||||
by using the command \c
|
||||
.B help\c
|
||||
\&.
|
||||
|
||||
You can run \c
|
||||
.B gdb\c
|
||||
\& with no arguments or options; but the most
|
||||
usual way to start GDB is with one argument or two, specifying an
|
||||
executable program as the argument:
|
||||
.sp
|
||||
.br
|
||||
gdb\ program
|
||||
.br
|
||||
.sp
|
||||
|
||||
You can also start with both an executable program and a core file specified:
|
||||
.sp
|
||||
.br
|
||||
gdb\ program\ core
|
||||
.br
|
||||
.sp
|
||||
|
||||
You can, instead, specify a process ID as a second argument, if you want
|
||||
to debug a running process:
|
||||
.sp
|
||||
.br
|
||||
gdb\ program\ 1234
|
||||
.br
|
||||
.sp
|
||||
|
||||
would attach GDB to process \c
|
||||
.B 1234\c
|
||||
\& (unless you also have a file
|
||||
named `\|\c
|
||||
.B 1234\c
|
||||
\&\|'; GDB does check for a core file first).
|
||||
|
||||
Here are some of the most frequently needed GDB commands:
|
||||
.TP
|
||||
.B break \fR[\|\fIfile\fB:\fR\|]\fIfunction
|
||||
\&
|
||||
Set a breakpoint at \c
|
||||
.I function\c
|
||||
\& (in \c
|
||||
.I file\c
|
||||
\&).
|
||||
.TP
|
||||
.B run \fR[\|\fIarglist\fR\|]
|
||||
Start your program (with \c
|
||||
.I arglist\c
|
||||
\&, if specified).
|
||||
.TP
|
||||
.B bt
|
||||
Backtrace: display the program stack.
|
||||
.TP
|
||||
.BI print " expr"\c
|
||||
\&
|
||||
Display the value of an expression.
|
||||
.TP
|
||||
.B c
|
||||
Continue running your program (after stopping, e.g. at a breakpoint).
|
||||
.TP
|
||||
.B next
|
||||
Execute next program line (after stopping); step \c
|
||||
.I over\c
|
||||
\& any
|
||||
function calls in the line.
|
||||
.TP
|
||||
.B step
|
||||
Execute next program line (after stopping); step \c
|
||||
.I into\c
|
||||
\& any
|
||||
function calls in the line.
|
||||
.TP
|
||||
.B help \fR[\|\fIname\fR\|]
|
||||
Show information about GDB command \c
|
||||
.I name\c
|
||||
\&, or general information
|
||||
about using GDB.
|
||||
.TP
|
||||
.B quit
|
||||
Exit from GDB.
|
||||
.PP
|
||||
For full details on GDB, see \c
|
||||
.I
|
||||
Using GDB: A Guide to the GNU Source-Level Debugger\c
|
||||
\&, by Richard M. Stallman and Roland H. Pesch. The same text is available online
|
||||
as the \c
|
||||
.B gdb\c
|
||||
\& entry in the \c
|
||||
.B info\c
|
||||
\& program.
|
||||
.SH OPTIONS
|
||||
Any arguments other than options specify an executable
|
||||
file and core file (or process ID); that is, the first argument
|
||||
encountered with no
|
||||
associated option flag is equivalent to a `\|\c
|
||||
.B \-se\c
|
||||
\&\|' option, and the
|
||||
second, if any, is equivalent to a `\|\c
|
||||
.B \-c\c
|
||||
\&\|' option if it's the name of a file. Many options have
|
||||
both long and short forms; both are shown here. The long forms are also
|
||||
recognized if you truncate them, so long as enough of the option is
|
||||
present to be unambiguous. (If you prefer, you can flag option
|
||||
arguments with `\|\c
|
||||
.B +\c
|
||||
\&\|' rather than `\|\c
|
||||
.B \-\c
|
||||
\&\|', though we illustrate the
|
||||
more usual convention.)
|
||||
|
||||
All the options and command line arguments you give are processed
|
||||
in sequential order. The order makes a difference when the
|
||||
`\|\c
|
||||
.B \-x\c
|
||||
\&\|' option is used.
|
||||
|
||||
.TP
|
||||
.B \-help
|
||||
.TP
|
||||
.B \-h
|
||||
List all options, with brief explanations.
|
||||
|
||||
.TP
|
||||
.BI "\-symbols=" "file"\c
|
||||
.TP
|
||||
.BI "\-s " "file"\c
|
||||
\&
|
||||
Read symbol table from file \c
|
||||
.I file\c
|
||||
\&.
|
||||
|
||||
.TP
|
||||
.BI "\-exec=" "file"\c
|
||||
.TP
|
||||
.BI "\-e " "file"\c
|
||||
\&
|
||||
Use file \c
|
||||
.I file\c
|
||||
\& as the executable file to execute when
|
||||
appropriate, and for examining pure data in conjunction with a core
|
||||
dump.
|
||||
|
||||
.TP
|
||||
.BI "\-se=" "file"\c
|
||||
\&
|
||||
Read symbol table from file \c
|
||||
.I file\c
|
||||
\& and use it as the executable
|
||||
file.
|
||||
|
||||
.TP
|
||||
.BI "\-core=" "file"\c
|
||||
.TP
|
||||
.BI "\-c " "file"\c
|
||||
\&
|
||||
Use file \c
|
||||
.I file\c
|
||||
\& as a core dump to examine.
|
||||
|
||||
.TP
|
||||
.BI "\-command=" "file"\c
|
||||
.TP
|
||||
.BI "\-x " "file"\c
|
||||
\&
|
||||
Execute GDB commands from file \c
|
||||
.I file\c
|
||||
\&.
|
||||
|
||||
.TP
|
||||
.BI "\-directory=" "directory"\c
|
||||
.TP
|
||||
.BI "\-d " "directory"\c
|
||||
\&
|
||||
Add \c
|
||||
.I directory\c
|
||||
\& to the path to search for source files.
|
||||
.PP
|
||||
|
||||
.TP
|
||||
.B \-nx
|
||||
.TP
|
||||
.B \-n
|
||||
Do not execute commands from any `\|\c
|
||||
.B .gdbinit\c
|
||||
\&\|' initialization files.
|
||||
Normally, the commands in these files are executed after all the
|
||||
command options and arguments have been processed.
|
||||
|
||||
|
||||
.TP
|
||||
.B \-quiet
|
||||
.TP
|
||||
.B \-q
|
||||
``Quiet''. Do not print the introductory and copyright messages. These
|
||||
messages are also suppressed in batch mode.
|
||||
|
||||
.TP
|
||||
.B \-batch
|
||||
Run in batch mode. Exit with status \c
|
||||
.B 0\c
|
||||
\& after processing all the command
|
||||
files specified with `\|\c
|
||||
.B \-x\c
|
||||
\&\|' (and `\|\c
|
||||
.B .gdbinit\c
|
||||
\&\|', if not inhibited).
|
||||
Exit with nonzero status if an error occurs in executing the GDB
|
||||
commands in the command files.
|
||||
|
||||
Batch mode may be useful for running GDB as a filter, for example to
|
||||
download and run a program on another computer; in order to make this
|
||||
more useful, the message
|
||||
.sp
|
||||
.br
|
||||
Program\ exited\ normally.
|
||||
.br
|
||||
.sp
|
||||
|
||||
(which is ordinarily issued whenever a program running under GDB control
|
||||
terminates) is not issued when running in batch mode.
|
||||
|
||||
.TP
|
||||
.BI "\-cd=" "directory"\c
|
||||
\&
|
||||
Run GDB using \c
|
||||
.I directory\c
|
||||
\& as its working directory,
|
||||
instead of the current directory.
|
||||
|
||||
.TP
|
||||
.B \-fullname
|
||||
.TP
|
||||
.B \-f
|
||||
Emacs sets this option when it runs GDB as a subprocess. It tells GDB
|
||||
to output the full file name and line number in a standard,
|
||||
recognizable fashion each time a stack frame is displayed (which
|
||||
includes each time the program stops). This recognizable format looks
|
||||
like two `\|\c
|
||||
.B \032\c
|
||||
\&\|' characters, followed by the file name, line number
|
||||
and character position separated by colons, and a newline. The
|
||||
Emacs-to-GDB interface program uses the two `\|\c
|
||||
.B \032\c
|
||||
\&\|' characters as
|
||||
a signal to display the source code for the frame.
|
||||
|
||||
.TP
|
||||
.B \-kernel
|
||||
.TP
|
||||
.B \-k
|
||||
Use gdb in kernel debugging mode. The prompt is set to ``(kgdb)''.
|
||||
|
||||
.TP
|
||||
.B \-wcore
|
||||
This option may only be used in kernel debugging mode while
|
||||
debugging a ``live'' kernel and makes the corefile (/dev/mem)
|
||||
writable.
|
||||
|
||||
.TP
|
||||
.BI "\-b " "bps"\c
|
||||
\&
|
||||
Set the line speed (baud rate or bits per second) of any serial
|
||||
interface used by GDB for remote debugging.
|
||||
|
||||
.TP
|
||||
.BI "\-tty=" "device"\c
|
||||
\&
|
||||
Run using \c
|
||||
.I device\c
|
||||
\& for your program's standard input and output.
|
||||
.PP
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.RB "`\|" gdb "\|'"
|
||||
entry in
|
||||
.B info\c
|
||||
\&;
|
||||
.I
|
||||
Using GDB: A Guide to the GNU Source-Level Debugger\c
|
||||
, Richard M. Stallman and Roland H. Pesch, July 1991.
|
||||
.SH COPYING
|
||||
Copyright (c) 1991 Free Software Foundation, Inc.
|
||||
.PP
|
||||
Permission is granted to make and distribute verbatim copies of
|
||||
this manual provided the copyright notice and this permission notice
|
||||
are preserved on all copies.
|
||||
.PP
|
||||
Permission is granted to copy and distribute modified versions of this
|
||||
manual under the conditions for verbatim copying, provided that the
|
||||
entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
.PP
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be included in
|
||||
translations approved by the Free Software Foundation instead of in
|
||||
the original English.
|
||||
@@ -1,23 +0,0 @@
|
||||
/* Host-dependent definitions for Intel 386 running BSD Unix, for GDB.
|
||||
Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#define HOST_BYTE_ORDER LITTLE_ENDIAN
|
||||
|
||||
#include <machine/limits.h> /* for INT_MIN, to avoid "INT_MIN
|
||||
redefined" warnings from defs.h */
|
||||
@@ -23,12 +23,13 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: kget.c,v 1.2 1999/01/19 23:15:56 abial Exp $
|
||||
* $Id: kget.c,v 1.1.2.1 1999/02/15 07:10:41 jkh Exp $
|
||||
*/
|
||||
|
||||
#include "sysinstall.h"
|
||||
#include "i386/isa/isa_device.h"
|
||||
#include <sys/sysctl.h>
|
||||
#include "i386/isa/isa_device.h"
|
||||
#include "i386/isa/pnp.h"
|
||||
|
||||
int
|
||||
kget(char *out)
|
||||
@@ -36,9 +37,11 @@ kget(char *out)
|
||||
int len, i, bytes_written = 0;
|
||||
char *buf;
|
||||
char *mib = "machdep.uc_devlist";
|
||||
char *mib2 = "machdep.uc_pnplist";
|
||||
char name[9];
|
||||
FILE *fout;
|
||||
struct isa_device *id;
|
||||
struct pnp_cinfo *c;
|
||||
char *p;
|
||||
|
||||
fout = fopen(out, "w");
|
||||
@@ -94,11 +97,54 @@ kget(char *out)
|
||||
}
|
||||
i += sizeof(struct isa_device) + 8;
|
||||
}
|
||||
if (bytes_written)
|
||||
fprintf(fout, "q\n");
|
||||
else
|
||||
unlink(out);
|
||||
free(buf), buf = NULL;
|
||||
/* Now, print the changes to PnP override table */
|
||||
i = sysctlbyname(mib2, NULL, &len, NULL, NULL);
|
||||
if (i) {
|
||||
msgDebug("kget: error sizing buffer\n");
|
||||
goto bail;
|
||||
}
|
||||
buf = (char *)malloc(len * sizeof(char));
|
||||
i = sysctlbyname(mib2, buf, &len, NULL, NULL);
|
||||
if (i) {
|
||||
msgDebug("kget: error retrieving data\n");
|
||||
goto bail;
|
||||
}
|
||||
i = 0;
|
||||
/* Print the PnP override table. Taken from userconfig.c */
|
||||
do {
|
||||
c = (struct pnp_cinfo *)(buf + i);
|
||||
if (c->csn >0 && c->csn != 255) {
|
||||
int pmax, mmax;
|
||||
|
||||
if (c->enable == 0) {
|
||||
bytes_written += fprintf(fout, "pnp %d %d disable\n",
|
||||
c->csn, c->ldn);
|
||||
continue;
|
||||
}
|
||||
bytes_written += fprintf(fout, "pnp %d %d %s irq0 %d irq1 %d drq0 %d drq1 %d",
|
||||
c->csn, c->ldn, c->override ? "os":"bios",
|
||||
c->irq[0], c->irq[1], c->drq[0], c->drq[1]);
|
||||
if (c->flags)
|
||||
bytes_written += fprintf(fout, " flags 0x%lx", c->flags);
|
||||
pmax = 0;
|
||||
while (c->port[pmax] != 0 && pmax < 8) {
|
||||
bytes_written += fprintf(fout, " port%d %d", pmax, c->port[pmax]);
|
||||
pmax++;
|
||||
}
|
||||
mmax = 0;
|
||||
while (c->mem[mmax].base != 0 && mmax < 8) {
|
||||
bytes_written += fprintf(fout, " mem%d %d",
|
||||
mmax, (int)c->mem[mmax].base);
|
||||
mmax++;
|
||||
}
|
||||
bytes_written += fprintf(fout,"\n");
|
||||
}
|
||||
} while ((i += sizeof(struct pnp_cinfo)) < len);
|
||||
bail:
|
||||
fprintf(fout, "q\n");
|
||||
fclose(fout);
|
||||
free(buf);
|
||||
if (buf)
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#
|
||||
# $Id: Makefile,v 1.2 1999/01/30 05:06:53 semen Exp $
|
||||
#
|
||||
|
||||
PROG= mount_ntfs
|
||||
SRCS= mount_ntfs.c getmntopts.c
|
||||
MAN8= mount_ntfs.8
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${.CURDIR}/../../sys -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1994 Christopher G. Demetriou
|
||||
* Copyright (c) 1999 Semen Ustimenko
|
||||
* 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 Christopher G. Demetriou.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*
|
||||
* $Id: mount_ntfs.c,v 1.2 1999/02/02 01:47:22 semen Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#define NTFS
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ntfs/ntfsmount.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mntopts.h"
|
||||
|
||||
static struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static gid_t a_gid __P((char *));
|
||||
static uid_t a_uid __P((char *));
|
||||
static mode_t a_mask __P((char *));
|
||||
static void usage __P((void)) __dead2;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct ntfs_args args;
|
||||
struct stat sb;
|
||||
int c, mntflags, set_gid, set_uid, set_mask,error;
|
||||
char *dev, *dir, ndir[MAXPATHLEN+1];
|
||||
#if __FreeBSD_version >= 300000
|
||||
struct vfsconf vfc;
|
||||
#else
|
||||
struct vfsconf *vfc;
|
||||
#endif
|
||||
|
||||
mntflags = set_gid = set_uid = set_mask = 0;
|
||||
(void)memset(&args, '\0', sizeof(args));
|
||||
|
||||
while ((c = getopt(argc, argv, "aiu:g:m:o:")) != -1) {
|
||||
switch (c) {
|
||||
case 'u':
|
||||
args.uid = a_uid(optarg);
|
||||
set_uid = 1;
|
||||
break;
|
||||
case 'g':
|
||||
args.gid = a_gid(optarg);
|
||||
set_gid = 1;
|
||||
break;
|
||||
case 'm':
|
||||
args.mode = a_mask(optarg);
|
||||
set_mask = 1;
|
||||
break;
|
||||
case 'i':
|
||||
args.flag |= NTFS_MFLAG_CASEINS;
|
||||
break;
|
||||
case 'a':
|
||||
args.flag |= NTFS_MFLAG_ALLNAMES;
|
||||
break;
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags, 0);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind + 2 != argc)
|
||||
usage();
|
||||
|
||||
dev = argv[optind];
|
||||
dir = argv[optind + 1];
|
||||
if (dir[0] != '/') {
|
||||
warnx("\"%s\" is a relative path", dir);
|
||||
if (getcwd(ndir, sizeof(ndir)) == NULL)
|
||||
err(EX_OSERR, "getcwd");
|
||||
strncat(ndir, "/", sizeof(ndir) - strlen(ndir) - 1);
|
||||
strncat(ndir, dir, sizeof(ndir) - strlen(ndir) - 1);
|
||||
dir = ndir;
|
||||
warnx("using \"%s\" instead", dir);
|
||||
}
|
||||
|
||||
args.fspec = dev;
|
||||
args.export.ex_root = 65534; /* unchecked anyway on DOS fs */
|
||||
if (mntflags & MNT_RDONLY)
|
||||
args.export.ex_flags = MNT_EXRDONLY;
|
||||
else
|
||||
args.export.ex_flags = 0;
|
||||
if (!set_gid || !set_uid || !set_mask) {
|
||||
if (stat(dir, &sb) == -1)
|
||||
err(EX_OSERR, "stat %s", dir);
|
||||
|
||||
if (!set_uid)
|
||||
args.uid = sb.st_uid;
|
||||
if (!set_gid)
|
||||
args.gid = sb.st_gid;
|
||||
if (!set_mask)
|
||||
args.mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
}
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
error = getvfsbyname("ntfs", &vfc);
|
||||
if(error && vfsisloadable("ntfs")) {
|
||||
if(vfsload("ntfs"))
|
||||
#else
|
||||
vfc = getvfsbyname("ntfs");
|
||||
if(!vfc && vfsisloadable("ntfs")) {
|
||||
if(vfsload("ntfs"))
|
||||
#endif
|
||||
err(EX_OSERR, "vfsload(ntfs)");
|
||||
endvfsent(); /* clear cache */
|
||||
#if __FreeBSD_version >= 300000
|
||||
error = getvfsbyname("ntfs", &vfc);
|
||||
#else
|
||||
vfc = getvfsbyname("ntfs");
|
||||
#endif
|
||||
}
|
||||
#if __FreeBSD_version >= 300000
|
||||
if (error)
|
||||
#else
|
||||
if (!vfc)
|
||||
#endif
|
||||
errx(EX_OSERR, "ntfs filesystem is not available");
|
||||
|
||||
#if __FreeBSD_version >= 300000
|
||||
if (mount(vfc.vfc_name, dir, mntflags, &args) < 0)
|
||||
#else
|
||||
if (mount(vfc->vfc_index, dir, mntflags, &args) < 0)
|
||||
#endif
|
||||
err(EX_OSERR, "%s", dev);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
gid_t
|
||||
a_gid(s)
|
||||
char *s;
|
||||
{
|
||||
struct group *gr;
|
||||
char *gname;
|
||||
gid_t gid;
|
||||
|
||||
if ((gr = getgrnam(s)) != NULL)
|
||||
gid = gr->gr_gid;
|
||||
else {
|
||||
for (gname = s; *s && isdigit(*s); ++s);
|
||||
if (!*s)
|
||||
gid = atoi(gname);
|
||||
else
|
||||
errx(EX_NOUSER, "unknown group id: %s", gname);
|
||||
}
|
||||
return (gid);
|
||||
}
|
||||
|
||||
uid_t
|
||||
a_uid(s)
|
||||
char *s;
|
||||
{
|
||||
struct passwd *pw;
|
||||
char *uname;
|
||||
uid_t uid;
|
||||
|
||||
if ((pw = getpwnam(s)) != NULL)
|
||||
uid = pw->pw_uid;
|
||||
else {
|
||||
for (uname = s; *s && isdigit(*s); ++s);
|
||||
if (!*s)
|
||||
uid = atoi(uname);
|
||||
else
|
||||
errx(EX_NOUSER, "unknown user id: %s", uname);
|
||||
}
|
||||
return (uid);
|
||||
}
|
||||
|
||||
mode_t
|
||||
a_mask(s)
|
||||
char *s;
|
||||
{
|
||||
int done, rv=0;
|
||||
char *ep;
|
||||
|
||||
done = 0;
|
||||
if (*s >= '0' && *s <= '7') {
|
||||
done = 1;
|
||||
rv = strtol(optarg, &ep, 8);
|
||||
}
|
||||
if (!done || rv < 0 || *ep)
|
||||
errx(EX_USAGE, "invalid file mode: %s", s);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, "usage: mount_ntfs [-a] [-i] [-u user] [-g group] [-m mask] bdev dir\n");
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
|
||||
A Network Address Translation Daemon for FreeBSD
|
||||
|
||||
|
||||
1. WHAT IS NATD ?
|
||||
|
||||
This is a simple daemon based on FreeBSD divert sockets
|
||||
which performs network address translation (or masquerading)
|
||||
for IP packets (see related RFCs 1631 and 1918).
|
||||
It is based on packet aliasing package (see README.alias)
|
||||
written by Charles Mott ([email protected]).
|
||||
|
||||
This package works with any network interface (doesn't have
|
||||
to be ppp). I run it on a computer having two ethernet cards,
|
||||
one connected to internet and the other one to local network.
|
||||
|
||||
2. GETTING IT RUNNING
|
||||
|
||||
1) Get FreeBSD 2.2 - I think the divert sockets are
|
||||
not available on earlier versions,
|
||||
|
||||
2) Compile this software by executing "make".
|
||||
|
||||
3) Install the software by executing "make install".
|
||||
|
||||
4) See man natd for further instructions.
|
||||
|
||||
3. FTP SITES FOR NATD
|
||||
|
||||
This package is available at ftp://ftp.suutari.iki.fi/pub/natd.
|
||||
|
||||
4. AUTHORS
|
||||
|
||||
This program is the result of the efforts of many people
|
||||
at different times:
|
||||
|
||||
Archie Cobbs <[email protected]> Divert sockets
|
||||
Charles Mott <[email protected]> Packet aliasing engine
|
||||
Eivind Eklund <[email protected]> Packet aliasing engine
|
||||
Ari Suutari <[email protected]> Natd
|
||||
Brian Somers <[email protected]> Manual page, glue and
|
||||
bunch of good ideas.
|
||||
|
||||
The original package written by Charles Mott
|
||||
is available at http://www.srv.net/~cmott.
|
||||
It is described in README.alias.
|
||||
|
||||
Happy Networking - comments and fixes are welcome!
|
||||
|
||||
Ari S. ([email protected])
|
||||
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
#
|
||||
# $Id:$
|
||||
#
|
||||
#
|
||||
# Configuration file for natd.
|
||||
#
|
||||
#
|
||||
# Enable logging to file /var/log/alias.log
|
||||
#
|
||||
log no
|
||||
#
|
||||
# Incoming connections. Should NEVER be set to "yes" if redirect_port,
|
||||
# redirect_address, or permanent_link statements are activated in this file!
|
||||
#
|
||||
# Setting to yes provides additional anti-crack protection
|
||||
#
|
||||
deny_incoming no
|
||||
#
|
||||
# Use sockets to avoid port clashes. Uses additional system resources, but
|
||||
# guarantees successful connections when port numbers conflict
|
||||
#
|
||||
use_sockets no
|
||||
#
|
||||
# Avoid port changes if possible when altering outbound packets. Makes rlogin
|
||||
# work in most cases.
|
||||
#
|
||||
same_port yes
|
||||
#
|
||||
# Verbose mode. Enables dumping of packets and disables
|
||||
# forking to background. Only set to yes for debugging.
|
||||
#
|
||||
verbose no
|
||||
#
|
||||
# Divert port. Can be a name in /etc/services or numeric value.
|
||||
#
|
||||
port 32000
|
||||
#
|
||||
# Interface name or address being aliased. Either one,
|
||||
# not both is required.
|
||||
#
|
||||
# Obtain interface name from the command output of "ifconfig -a"
|
||||
#
|
||||
# alias_address 192.168.0.1
|
||||
interface ep0
|
||||
#
|
||||
# Alias unregistered addresses or all addresses. Set this to yes if
|
||||
# the inside network is all RFC1918 addresses.
|
||||
#
|
||||
unregistered_only no
|
||||
#
|
||||
# Configure permanent links. If you use host names instead
|
||||
# of addresses here, be sure that name server works BEFORE
|
||||
# natd is up - this is usually not the case. So either use
|
||||
# numeric addresses or hosts that are in /etc/hosts.
|
||||
#
|
||||
# Note: Current versions of FreeBSD all call /etc/rc.firewall
|
||||
# BEFORE running named, so if the DNS server and NAT are on the same
|
||||
# machine, the nameserver won't be up if natd is called from /etc/rc.firewall
|
||||
#
|
||||
# Map connections coming to port 30000 to telnet in my_private_host.
|
||||
# Remember to allow the connection /etc/rc.firewall also.
|
||||
#
|
||||
# The following permanent_link and redirect_port statements are equivalent
|
||||
#permanent_link tcp my_private_host:telnet 0.0.0.0:0 30000
|
||||
#redirect_port tcp my_private_host:telnet 30000
|
||||
#
|
||||
# Map connections coming from host.xyz.com to port 30001 to
|
||||
# telnet in another_host.
|
||||
#permanent_link tcp another_host:telnet host.xyz.com:0 30001
|
||||
#
|
||||
# Static NAT address mapping:
|
||||
#
|
||||
# ipconfig must apply any legal IP numbers that inside hosts
|
||||
# will be known by to the outside interface. These are sometimes known as
|
||||
# virtual IP numbers. It's suggested to use the "interface" directive
|
||||
# instead of the "alias_address" directive to make it more clear what is
|
||||
# going on. (although both will work)
|
||||
#
|
||||
# DNS in this situation can get hairy. For example, an inside host
|
||||
# named aweb.company.com is located at 192.168.1.56, and needs to be
|
||||
# accessible through a legal IP number like 198.105.232.1. If both
|
||||
# 192.168.1.56 and 198.105.232.1 are set up as address records in the DNS
|
||||
# for aweb.company.com, then external hosts attempting to access
|
||||
# aweb.company.com may use address 192.168.1.56 which is inaccessible to them.
|
||||
#
|
||||
# The obvious solution is to use only a single address for the name, the
|
||||
# outside address. However, this creates needless traffic through the
|
||||
# NAT, because inside hosts will go through the NAT to get to the legal
|
||||
# number, even when the inside number is on the same subnet as they are!
|
||||
#
|
||||
# It's probably not a good idea to use DNS names in redirect_address statements
|
||||
#
|
||||
#The following mapping points outside address 198.105.232.1 to 192.168.1.56
|
||||
#redirect_address 192.168.1.56 198.105.232.1
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# != 1 ]
|
||||
then
|
||||
echo "usage: natd.test ifname"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ipfw flush
|
||||
ipfw add divert 32000 ip from any to any via $1
|
||||
ipfw add pass ip from any to any
|
||||
|
||||
./natd -port 32000 -interface $1 -verbose
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $Id$
|
||||
|
||||
PROG= sysctl
|
||||
MAN8= sysctl.8
|
||||
|
||||
BINDIR= /sbin
|
||||
NOSHARED?= yes
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)pathconf.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PC_NAMES { \
|
||||
{ 0, 0 }, \
|
||||
{ "link_max", CTLTYPE_INT }, \
|
||||
{ "max_canon", CTLTYPE_INT }, \
|
||||
{ "max_input", CTLTYPE_INT }, \
|
||||
{ "name_max", CTLTYPE_INT }, \
|
||||
{ "path_max", CTLTYPE_INT }, \
|
||||
{ "pipe_buf", CTLTYPE_INT }, \
|
||||
{ "chown_restricted", CTLTYPE_INT }, \
|
||||
{ "no_trunc", CTLTYPE_INT }, \
|
||||
{ "vdisable", CTLTYPE_INT }, \
|
||||
}
|
||||
#define PC_MAXID 10
|
||||
|
||||
struct ctlname pcnames[] = PC_NAMES;
|
||||
char names[BUFSIZ];
|
||||
|
||||
struct list {
|
||||
struct ctlname *list;
|
||||
int size;
|
||||
};
|
||||
struct list pclist = { pcnames, PC_MAXID };
|
||||
|
||||
int Aflag, aflag, nflag, wflag, stdinflag;
|
||||
|
||||
int findname __P((char *, char *, char**, struct list *));
|
||||
void listall __P((char *, struct list *));
|
||||
void parse __P((char *, char *, int));
|
||||
static void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char *path;
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "Aan")) != -1) {
|
||||
switch (ch) {
|
||||
|
||||
case 'A':
|
||||
Aflag = 1;
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
aflag = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
nflag = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
usage();
|
||||
path = *argv++;
|
||||
if (strcmp(path, "-") == 0)
|
||||
stdinflag = 1;
|
||||
argc--;
|
||||
if (Aflag || aflag) {
|
||||
listall(path, &pclist);
|
||||
exit(0);
|
||||
}
|
||||
if (argc == 0)
|
||||
usage();
|
||||
while (argc-- > 0)
|
||||
parse(path, *argv, 1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* List all variables known to the system.
|
||||
*/
|
||||
void
|
||||
listall(path, lp)
|
||||
char *path;
|
||||
struct list *lp;
|
||||
{
|
||||
int lvl2;
|
||||
|
||||
if (lp->list == 0)
|
||||
return;
|
||||
for (lvl2 = 0; lvl2 < lp->size; lvl2++) {
|
||||
if (lp->list[lvl2].ctl_name == 0)
|
||||
continue;
|
||||
parse(path, lp->list[lvl2].ctl_name, Aflag);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a name into an index.
|
||||
* Lookup and print out the attribute if it exists.
|
||||
*/
|
||||
void
|
||||
parse(pathname, string, flags)
|
||||
char *pathname;
|
||||
char *string;
|
||||
int flags;
|
||||
{
|
||||
int indx, value;
|
||||
char *bufp, buf[BUFSIZ];
|
||||
|
||||
bufp = buf;
|
||||
snprintf(buf, BUFSIZ, "%s", string);
|
||||
if ((indx = findname(string, "top", &bufp, &pclist)) == -1)
|
||||
return;
|
||||
if (bufp) {
|
||||
warnx("name %s in %s is unknown", *bufp, string);
|
||||
return;
|
||||
}
|
||||
if (stdinflag)
|
||||
value = fpathconf(0, indx);
|
||||
else
|
||||
value = pathconf(pathname, indx);
|
||||
if (value == -1) {
|
||||
if (flags == 0)
|
||||
return;
|
||||
switch (errno) {
|
||||
case EOPNOTSUPP:
|
||||
warnx("%s: value is not available", string);
|
||||
return;
|
||||
case ENOTDIR:
|
||||
warnx("%s: specification is incomplete", string);
|
||||
return;
|
||||
case ENOMEM:
|
||||
warnx("%s: type is unknown to this program", string);
|
||||
return;
|
||||
default:
|
||||
warn("%s", string);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!nflag)
|
||||
fprintf(stdout, "%s = ", string);
|
||||
fprintf(stdout, "%d\n", value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan a list of names searching for a particular name.
|
||||
*/
|
||||
int
|
||||
findname(string, level, bufp, namelist)
|
||||
char *string;
|
||||
char *level;
|
||||
char **bufp;
|
||||
struct list *namelist;
|
||||
{
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
|
||||
warnx("%s: incomplete specification", string);
|
||||
return (-1);
|
||||
}
|
||||
for (i = 0; i < namelist->size; i++)
|
||||
if (namelist->list[i].ctl_name != NULL &&
|
||||
strcmp(name, namelist->list[i].ctl_name) == 0)
|
||||
break;
|
||||
if (i == namelist->size) {
|
||||
warnx("%s level name %s in %s is invalid", level, name, string);
|
||||
return (-1);
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "%s\n%s\n%s\n",
|
||||
"usage: pathname [-n] variable ...",
|
||||
" pathname [-n] -a",
|
||||
" pathname [-n] -A");
|
||||
exit(1);
|
||||
}
|
||||
@@ -1,243 +0,0 @@
|
||||
.\" Copyright (c) 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.
|
||||
.\"
|
||||
.\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93
|
||||
.\" $Id: sysctl.8,v 1.17 1998/09/29 02:01:06 jkoshy Exp $
|
||||
.\"
|
||||
.Dd September 23, 1994
|
||||
.Dt SYSCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sysctl
|
||||
.Nd get or set kernel state
|
||||
.Sh SYNOPSIS
|
||||
.Nm sysctl
|
||||
.Op Fl bdn
|
||||
.Ar name ...
|
||||
.Nm sysctl
|
||||
.Op Fl bn
|
||||
.Fl w
|
||||
.Ar name=value ...
|
||||
.Nm sysctl
|
||||
.Op Fl bdn
|
||||
.Fl aAX
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility retrieves kernel state and allows processes with
|
||||
appropriate privilege to set kernel state.
|
||||
The state to be retrieved or set is described using a
|
||||
``Management Information Base'' (``MIB'') style name,
|
||||
described as a dotted set of components.
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl a
|
||||
List all the currently available string or integer values.
|
||||
.It Fl A
|
||||
List all the known MIB names including opaques.
|
||||
Those with string or integer values will be printed as with the
|
||||
.Fl a
|
||||
flag; for the opaque values,
|
||||
information about the format and the length is printed in addition the first
|
||||
few bytes is dumped in hex.
|
||||
.It Fl X
|
||||
Same as
|
||||
.Fl A
|
||||
except the entire value of opaque variables is hexdumped.
|
||||
.It Fl n
|
||||
Specify that the printing of the field name should be
|
||||
suppressed and that only its value should be output.
|
||||
This flag is useful for setting shell variables.
|
||||
For example, to save the pagesize in variable psize, use:
|
||||
.Bd -literal -offset indent -compact
|
||||
set psize=`sysctl -n hw.pagesize`
|
||||
.Ed
|
||||
.It Fl b
|
||||
Force the value of the variable(s) to be output in raw, binary
|
||||
format. No names are printed and no terminating newlines are output.
|
||||
This is mostly useful with a single variable.
|
||||
.It Fl d
|
||||
Display the description rather than the value of the requested
|
||||
variable(s).
|
||||
.It Fl w Ar name=value ...
|
||||
Set the MIB
|
||||
.Ar name
|
||||
to the new
|
||||
.Ar value .
|
||||
If just a MIB style
|
||||
.Ar name
|
||||
is given,
|
||||
the corresponding value is retrieved.
|
||||
.El
|
||||
.Pp
|
||||
The information available from
|
||||
.Nm
|
||||
consists of integers, strings, and opaques.
|
||||
.Nm Sysctl
|
||||
only knows about a couple of opaque types, and will resort to hexdumps
|
||||
for the rest.
|
||||
The opaque information is much more useful if retrieved by special
|
||||
purpose programs such as
|
||||
.Nm ps ,
|
||||
.Nm systat ,
|
||||
and
|
||||
.Nm netstat .
|
||||
.Pp
|
||||
The string and integer information is summarized below.
|
||||
For a detailed description of these variable see
|
||||
.Xr sysctl 3 .
|
||||
.Pp
|
||||
The changeable column indicates whether a process with appropriate
|
||||
privilege can change the value.
|
||||
.Bl -column net.inet.ip.forwardingxxxxxx integerxxx
|
||||
.It Sy Name Type Changeable
|
||||
.It kern.ostype string no
|
||||
.It kern.osrelease string no
|
||||
.It kern.osrevision integer no
|
||||
.It kern.version string no
|
||||
.It kern.maxvnodes integer yes
|
||||
.It kern.maxproc integer no
|
||||
.It kern.maxprocperuid integer yes
|
||||
.It kern.maxfiles integer yes
|
||||
.It kern.maxfilesperproc integer yes
|
||||
.It kern.argmax integer no
|
||||
.It kern.securelevel integer raise only
|
||||
.It kern.hostname string yes
|
||||
.It kern.hostid integer yes
|
||||
.It kern.clockrate struct no
|
||||
.It kern.posix1version integer no
|
||||
.It kern.ngroups integer no
|
||||
.It kern.job_control integer no
|
||||
.It kern.saved_ids integer no
|
||||
.It kern.boottime struct no
|
||||
.It kern.domainname string yes
|
||||
.It kern.update integer yes
|
||||
.It kern.osreldate string no
|
||||
.It kern.bootfile string yes
|
||||
.It kern.corefile string yes
|
||||
.It kern.logsigexit integer yes
|
||||
.It vm.loadavg struct no
|
||||
.It hw.machine string no
|
||||
.It hw.model string no
|
||||
.It hw.ncpu integer no
|
||||
.It hw.byteorder integer no
|
||||
.It hw.physmem integer no
|
||||
.It hw.usermem integer no
|
||||
.It hw.pagesize integer no
|
||||
.It hw.floatingpoint integer no
|
||||
.It hw.machine_arch string no
|
||||
.It machdep.console_device dev_t no
|
||||
.It machdep.adjkerntz integer yes
|
||||
.It machdep.disable_rtc_set integer yes
|
||||
.It user.cs_path string no
|
||||
.It user.bc_base_max integer no
|
||||
.It user.bc_dim_max integer no
|
||||
.It user.bc_scale_max integer no
|
||||
.It user.bc_string_max integer no
|
||||
.It user.coll_weights_max integer no
|
||||
.It user.expr_nest_max integer no
|
||||
.It user.line_max integer no
|
||||
.It user.re_dup_max integer no
|
||||
.It user.posix2_version integer no
|
||||
.It user.posix2_c_bind integer no
|
||||
.It user.posix2_c_dev integer no
|
||||
.It user.posix2_char_term integer no
|
||||
.It user.posix2_fort_dev integer no
|
||||
.It user.posix2_fort_run integer no
|
||||
.It user.posix2_localedef integer no
|
||||
.It user.posix2_sw_dev integer no
|
||||
.It user.posix2_upe integer no
|
||||
.It user.stream_max integer no
|
||||
.It user.tzname_max integer no
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
For example, to retrieve the maximum number of processes allowed
|
||||
in the system, one would use the follow request:
|
||||
.Bd -literal -offset indent -compact
|
||||
sysctl kern.maxproc
|
||||
.Ed
|
||||
.Pp
|
||||
To set the maximum number of processes allowed
|
||||
per uid to 1000, one would use the follow request:
|
||||
.Bd -literal -offset indent -compact
|
||||
sysctl -w kern.maxprocperuid=1000
|
||||
.Ed
|
||||
.Pp
|
||||
Information about the system clock rate may be obtained with:
|
||||
.Bd -literal -offset indent -compact
|
||||
sysctl kern.clockrate
|
||||
.Ed
|
||||
.Pp
|
||||
Information about the load average history may be obtained with:
|
||||
.Bd -literal -offset indent -compact
|
||||
sysctl vm.loadavg
|
||||
.Ed
|
||||
.Pp
|
||||
More variables than these exist, and the best and likely only place
|
||||
to search for their deeper meaning is undoubtedly the source where
|
||||
they are defined.
|
||||
.Sh FILES
|
||||
.Bl -tag -width <netinet/icmpXvar.h> -compact
|
||||
.It Pa <sys/sysctl.h>
|
||||
definitions for top level identifiers, second level kernel and hardware
|
||||
identifiers, and user level identifiers
|
||||
.It Pa <sys/socket.h>
|
||||
definitions for second level network identifiers
|
||||
.It Pa <sys/gmon.h>
|
||||
definitions for third level profiling identifiers
|
||||
.It Pa <vm/vm_param.h>
|
||||
definitions for second level virtual memory identifiers
|
||||
.It Pa <netinet/in.h>
|
||||
definitions for third level Internet identifiers and
|
||||
fourth level IP identifiers
|
||||
.It Pa <netinet/icmp_var.h>
|
||||
definitions for fourth level ICMP identifiers
|
||||
.It Pa <netinet/udp_var.h>
|
||||
definitions for fourth level UDP identifiers
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr sysctl 3
|
||||
.Sh BUGS
|
||||
.Nm Sysctl
|
||||
presently exploits an undocumented interface to the kernel
|
||||
sysctl facility to traverse the sysctl tree and to retrieve format
|
||||
and name information.
|
||||
This correct interface is being thought about for the time being.
|
||||
.Sh HISTORY
|
||||
.Nm Sysctl
|
||||
first appeared in
|
||||
.Bx 4.4 .
|
||||
.Pp
|
||||
In
|
||||
.Fx 2.2 ,
|
||||
.Nm
|
||||
was significantly remodeled.
|
||||
@@ -1,502 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] =
|
||||
"@(#) Copyright (c) 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
static const char rcsid[] =
|
||||
"$Id: sysctl.c,v 1.19 1998/11/08 19:27:43 phk Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int Aflag, aflag, bflag, dflag, nflag, wflag, Xflag;
|
||||
|
||||
static int oidfmt(int *, int, char *, u_int *);
|
||||
static void parse(char *);
|
||||
static int show_var(int *, int);
|
||||
static int sysctl_all (int *oid, int len);
|
||||
static int name2oid(char *, int *);
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
|
||||
"usage: sysctl [-bdn] variable ...",
|
||||
" sysctl [-bn] -w variable=value ...",
|
||||
" sysctl [-bdn] -a",
|
||||
" sysctl [-bdn] -A",
|
||||
" sysctl [-bdn] -X");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
setbuf(stdout,0);
|
||||
setbuf(stderr,0);
|
||||
|
||||
while ((ch = getopt(argc, argv, "AabdnwX")) != -1) {
|
||||
switch (ch) {
|
||||
case 'A': Aflag = 1; break;
|
||||
case 'a': aflag = 1; break;
|
||||
case 'b': bflag = 1; break;
|
||||
case 'd': dflag = 1; break;
|
||||
case 'n': nflag = 1; break;
|
||||
case 'w': wflag = 1; break;
|
||||
case 'X': Xflag = Aflag = 1; break;
|
||||
default: usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (wflag && (Aflag || aflag || dflag))
|
||||
usage();
|
||||
if (Aflag || aflag)
|
||||
exit (sysctl_all(0, 0));
|
||||
if (argc == 0)
|
||||
usage();
|
||||
while (argc-- > 0)
|
||||
parse(*argv++);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a name into a MIB entry.
|
||||
* Lookup and print out the MIB entry if it exists.
|
||||
* Set a new value if requested.
|
||||
*/
|
||||
static void
|
||||
parse(char *string)
|
||||
{
|
||||
int len, i, j;
|
||||
void *newval = 0;
|
||||
int intval, newsize = 0;
|
||||
quad_t quadval;
|
||||
int mib[CTL_MAXNAME];
|
||||
char *cp, *bufp, buf[BUFSIZ];
|
||||
u_int kind;
|
||||
|
||||
bufp = buf;
|
||||
snprintf(buf, BUFSIZ, "%s", string);
|
||||
if ((cp = strchr(string, '=')) != NULL) {
|
||||
if (!wflag)
|
||||
errx(2, "must specify -w to set variables");
|
||||
*strchr(buf, '=') = '\0';
|
||||
*cp++ = '\0';
|
||||
while (isspace(*cp))
|
||||
cp++;
|
||||
newval = cp;
|
||||
newsize = strlen(cp);
|
||||
} else {
|
||||
if (wflag)
|
||||
usage();
|
||||
}
|
||||
len = name2oid(bufp, mib);
|
||||
|
||||
if (len < 0)
|
||||
errx(1, "unknown oid '%s'", bufp);
|
||||
|
||||
if (oidfmt(mib, len, 0, &kind))
|
||||
err(1, "couldn't find format of oid '%s'", bufp);
|
||||
|
||||
if (!wflag) {
|
||||
if ((kind & CTLTYPE) == CTLTYPE_NODE) {
|
||||
sysctl_all(mib, len);
|
||||
} else {
|
||||
i = show_var(mib, len);
|
||||
if (!i && !bflag)
|
||||
putchar('\n');
|
||||
}
|
||||
} else {
|
||||
if ((kind & CTLTYPE) == CTLTYPE_NODE)
|
||||
errx(1, "oid '%s' isn't a leaf node", bufp);
|
||||
|
||||
if (!(kind&CTLFLAG_WR))
|
||||
errx(1, "oid '%s' is read only", bufp);
|
||||
|
||||
switch (kind & CTLTYPE) {
|
||||
case CTLTYPE_INT:
|
||||
intval = atoi(newval);
|
||||
newval = &intval;
|
||||
newsize = sizeof intval;
|
||||
break;
|
||||
break;
|
||||
case CTLTYPE_STRING:
|
||||
break;
|
||||
case CTLTYPE_QUAD:
|
||||
break;
|
||||
sscanf(newval, "%qd", &quadval);
|
||||
newval = &quadval;
|
||||
newsize = sizeof quadval;
|
||||
break;
|
||||
default:
|
||||
errx(1, "oid '%s' is type %d,"
|
||||
" cannot set that", bufp,
|
||||
kind & CTLTYPE);
|
||||
}
|
||||
|
||||
i = show_var(mib, len);
|
||||
if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
|
||||
if (!i && !bflag)
|
||||
putchar('\n');
|
||||
switch (errno) {
|
||||
case EOPNOTSUPP:
|
||||
errx(1, "%s: value is not available",
|
||||
string);
|
||||
case ENOTDIR:
|
||||
errx(1, "%s: specification is incomplete",
|
||||
string);
|
||||
case ENOMEM:
|
||||
errx(1, "%s: type is unknown to this program",
|
||||
string);
|
||||
default:
|
||||
warn("%s", string);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!bflag)
|
||||
printf(" -> ");
|
||||
i = nflag;
|
||||
nflag = 1;
|
||||
j = show_var(mib, len);
|
||||
if (!j && !bflag)
|
||||
putchar('\n');
|
||||
nflag = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* These functions will dump out various interesting structures. */
|
||||
|
||||
static int
|
||||
S_clockinfo(int l2, void *p)
|
||||
{
|
||||
struct clockinfo *ci = (struct clockinfo*)p;
|
||||
if (l2 != sizeof *ci)
|
||||
err(1, "S_clockinfo %d != %d", l2, sizeof *ci);
|
||||
printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
|
||||
ci->hz, ci->tick, ci->tickadj, ci->profhz, ci->stathz);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
S_loadavg(int l2, void *p)
|
||||
{
|
||||
struct loadavg *tv = (struct loadavg*)p;
|
||||
|
||||
if (l2 != sizeof *tv)
|
||||
err(1, "S_loadavg %d != %d", l2, sizeof *tv);
|
||||
|
||||
printf("{ %.2f %.2f %.2f }",
|
||||
(double)tv->ldavg[0]/(double)tv->fscale,
|
||||
(double)tv->ldavg[1]/(double)tv->fscale,
|
||||
(double)tv->ldavg[2]/(double)tv->fscale);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
S_timeval(int l2, void *p)
|
||||
{
|
||||
struct timeval *tv = (struct timeval*)p;
|
||||
time_t tv_sec;
|
||||
char *p1, *p2;
|
||||
|
||||
if (l2 != sizeof *tv)
|
||||
err(1, "S_timeval %d != %d", l2, sizeof *tv);
|
||||
printf("{ sec = %ld, usec = %ld } ",
|
||||
tv->tv_sec, tv->tv_usec);
|
||||
tv_sec = tv->tv_sec;
|
||||
p1 = strdup(ctime(&tv_sec));
|
||||
for (p2=p1; *p2 ; p2++)
|
||||
if (*p2 == '\n')
|
||||
*p2 = '\0';
|
||||
fputs(p1, stdout);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
T_dev_t(int l2, void *p)
|
||||
{
|
||||
dev_t *d = (dev_t *)p;
|
||||
if (l2 != sizeof *d)
|
||||
err(1, "T_dev_T %d != %d", l2, sizeof *d);
|
||||
printf("{ major = %d, minor = %d }",
|
||||
major(*d), minor(*d));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions uses a presently undocumented interface to the kernel
|
||||
* to walk the tree and get the type so it can print the value.
|
||||
* This interface is under work and consideration, and should probably
|
||||
* be killed with a big axe by the first person who can find the time.
|
||||
* (be aware though, that the proper interface isn't as obvious as it
|
||||
* may seem, there are various conflicting requirements.
|
||||
*/
|
||||
|
||||
static int
|
||||
name2oid(char *name, int *oidp)
|
||||
{
|
||||
int oid[2];
|
||||
int i;
|
||||
size_t j;
|
||||
|
||||
oid[0] = 0;
|
||||
oid[1] = 3;
|
||||
|
||||
j = CTL_MAXNAME * sizeof (int);
|
||||
i = sysctl(oid, 2, oidp, &j, name, strlen(name));
|
||||
if (i < 0)
|
||||
return i;
|
||||
j /= sizeof (int);
|
||||
return (j);
|
||||
}
|
||||
|
||||
static int
|
||||
oidfmt(int *oid, int len, char *fmt, u_int *kind)
|
||||
{
|
||||
int qoid[CTL_MAXNAME+2];
|
||||
u_char buf[BUFSIZ];
|
||||
int i;
|
||||
size_t j;
|
||||
|
||||
qoid[0] = 0;
|
||||
qoid[1] = 4;
|
||||
memcpy(qoid + 2, oid, len * sizeof(int));
|
||||
|
||||
j = sizeof buf;
|
||||
i = sysctl(qoid, len + 2, buf, &j, 0, 0);
|
||||
if (i)
|
||||
err(1, "sysctl fmt %d %d %d", i, j, errno);
|
||||
|
||||
if (kind)
|
||||
*kind = *(u_int *)buf;
|
||||
|
||||
if (fmt)
|
||||
strcpy(fmt, (char *)(buf + sizeof(u_int)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This formats and outputs the value of one variable
|
||||
*
|
||||
* Returns zero if anything was actually output.
|
||||
* Returns one if didn't know what to do with this.
|
||||
* Return minus one if we had errors.
|
||||
*/
|
||||
|
||||
static int
|
||||
show_var(int *oid, int nlen)
|
||||
{
|
||||
u_char buf[BUFSIZ], *val, *p;
|
||||
char name[BUFSIZ], descr[BUFSIZ], *fmt;
|
||||
int qoid[CTL_MAXNAME+2];
|
||||
int i;
|
||||
size_t j, len;
|
||||
u_int kind;
|
||||
int (*func)(int, void *) = 0;
|
||||
|
||||
qoid[0] = 0;
|
||||
memcpy(qoid + 2, oid, nlen * sizeof(int));
|
||||
|
||||
qoid[1] = 1;
|
||||
j = sizeof name;
|
||||
i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
|
||||
if (i || !j)
|
||||
err(1, "sysctl name %d %d %d", i, j, errno);
|
||||
|
||||
if (dflag) {
|
||||
qoid[1] = 5;
|
||||
j = sizeof descr;
|
||||
i = sysctl(qoid, nlen + 2, descr, &j, 0, 0);
|
||||
if (i || !j)
|
||||
err(1, "sysctl name %d %d %d", i, j, errno);
|
||||
if (!nflag)
|
||||
printf("%s: ", name);
|
||||
printf("%s", descr[0] ? descr : "[no description]");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* find an estimate of how much we need for this var */
|
||||
j = 0;
|
||||
i = sysctl(oid, nlen, 0, &j, 0, 0);
|
||||
j += j; /* we want to be sure :-) */
|
||||
|
||||
val = alloca(j);
|
||||
len = j;
|
||||
i = sysctl(oid, nlen, val, &len, 0, 0);
|
||||
if (i || !len)
|
||||
return (1);
|
||||
|
||||
if (bflag) {
|
||||
fwrite(val, 1, len, stdout);
|
||||
return (0);
|
||||
}
|
||||
|
||||
qoid[1] = 4;
|
||||
j = sizeof buf;
|
||||
i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
|
||||
if (i || !j)
|
||||
err(1, "sysctl fmt %d %d %d", i, j, errno);
|
||||
|
||||
kind = *(u_int *)buf;
|
||||
|
||||
fmt = (char *)(buf + sizeof(u_int));
|
||||
|
||||
p = val;
|
||||
switch (*fmt) {
|
||||
case 'A':
|
||||
if (!nflag)
|
||||
printf("%s: ", name);
|
||||
printf("%s", p);
|
||||
return (0);
|
||||
|
||||
case 'I':
|
||||
if (!nflag)
|
||||
printf("%s: ", name);
|
||||
val = "";
|
||||
while (len >= sizeof(int)) {
|
||||
printf("%s%d", val, *(int *)p);
|
||||
val = " ";
|
||||
len -= sizeof (int);
|
||||
p += sizeof (int);
|
||||
}
|
||||
return (0);
|
||||
|
||||
case 'L':
|
||||
if (!nflag)
|
||||
printf("%s: ", name);
|
||||
printf("%ld", *(long *)p);
|
||||
return (0);
|
||||
|
||||
case 'P':
|
||||
if (!nflag)
|
||||
printf("%s: ", name);
|
||||
printf("%p", *(void **)p);
|
||||
return (0);
|
||||
|
||||
case 'T':
|
||||
case 'S':
|
||||
i = 0;
|
||||
if (!strcmp(fmt, "S,clockinfo")) func = S_clockinfo;
|
||||
else if (!strcmp(fmt, "S,timeval")) func = S_timeval;
|
||||
else if (!strcmp(fmt, "S,loadavg")) func = S_loadavg;
|
||||
else if (!strcmp(fmt, "T,dev_t")) func = T_dev_t;
|
||||
if (func) {
|
||||
if (!nflag)
|
||||
printf("%s: ", name);
|
||||
return ((*func)(len, p));
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
default:
|
||||
if (!Aflag)
|
||||
return (1);
|
||||
if (!nflag)
|
||||
printf("%s: ", name);
|
||||
printf("Format:%s Length:%d Dump:0x", fmt, len);
|
||||
while (len--) {
|
||||
printf("%02x", *p++);
|
||||
if (Xflag || p < val+16)
|
||||
continue;
|
||||
printf("...");
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_all (int *oid, int len)
|
||||
{
|
||||
int name1[22], name2[22];
|
||||
int i, j;
|
||||
size_t l1, l2;
|
||||
|
||||
name1[0] = 0;
|
||||
name1[1] = 2;
|
||||
l1 = 2;
|
||||
if (len) {
|
||||
memcpy(name1+2, oid, len*sizeof (int));
|
||||
l1 += len;
|
||||
} else {
|
||||
name1[2] = 1;
|
||||
l1++;
|
||||
}
|
||||
while (1) {
|
||||
l2 = sizeof name2;
|
||||
j = sysctl(name1, l1, name2, &l2, 0, 0);
|
||||
if (j < 0)
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
err(1, "sysctl(getnext) %d %d", j, l2);
|
||||
|
||||
l2 /= sizeof (int);
|
||||
|
||||
if (l2 < len)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
if (name2[i] != oid[i])
|
||||
return 0;
|
||||
|
||||
i = show_var(name2, l2);
|
||||
if (!i && !bflag)
|
||||
putchar('\n');
|
||||
|
||||
memcpy(name1+2, name2, l2*sizeof (int));
|
||||
l1 = 2 + l2;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
kernel, rc.local, and xdm-config are typically softlinks. Plus other
|
||||
files, of course, depending on how you setup your system.
|
||||
|
||||
rc.local and xdm-config might be softlinks into HT.DISKLESS, allowing
|
||||
you to ease system administration when managing many diskless
|
||||
workstations. You can also play other tricks, such as I play in
|
||||
rc.conf.local by having it source ../HT.DISKLESS/rc.conf.local to get
|
||||
class-based defaults.
|
||||
|
||||
Note: the ttys file below contains an example of how to have X startup
|
||||
on boot.
|
||||
|
||||
apollo:/conf/209.157.86.12# ls -la
|
||||
total 7
|
||||
drwxr-xr-x 2 root wheel 512 Feb 9 00:27 .
|
||||
drwxr-xr-x 8 root wheel 512 Feb 8 22:48 ..
|
||||
lrwxr-xr-x 1 root wheel 20 Feb 8 22:04 fstab -> ../HT.DISKLESS/fstab
|
||||
lrwxr-xr-x 1 root wheel 17 Jan 24 23:33 kernel -> /kernel.diskless2
|
||||
-rw-r--r-- 1 root wheel 133 Feb 8 22:04 rc.conf.local
|
||||
lrwxr-xr-x 1 root wheel 23 Jan 25 00:41 rc.local -> ../HT.DISKLESS/rc.local
|
||||
-rw------- 1 root wheel 539 Jan 17 15:29 ssh_host_key
|
||||
-rw-r--r-- 1 root wheel 343 Jan 17 15:29 ssh_host_key.pub
|
||||
lrwxr-xr-x 1 root wheel 26 Feb 9 00:27 syslog.conf -> ../HT.DISKLESS/syslog.conf
|
||||
-rw-r--r-- 1 root wheel 1408 Feb 8 19:54 ttys
|
||||
lrwxr-xr-x 1 root wheel 25 Jan 25 00:38 xdm-config -> ../HT.DISKLESS/xdm-config
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# DISKLESS RC.CONF.LOCAL
|
||||
#
|
||||
# Override system standard /etc/rc.conf
|
||||
|
||||
. /conf/HT.DISKLESS/rc.conf.local
|
||||
|
||||
hostname=test2.backplane.com
|
||||
start_xdm=NO
|
||||
|
||||
Binary file not shown.
@@ -1 +0,0 @@
|
||||
1024 33 131532587310298436102876167134780549224884868848048954510241288010381123823834489593599651234236801895942903979896941799980786675282403650831462626987993609590967535749256449810953893747928248417183421903403076895749793372279190481189373438759742396152779236777836204647146078686957945395785442097357022574693 [email protected]
|
||||
@@ -1,5 +0,0 @@
|
||||
# fstab for diskless machine. Root is already mounted, as is swap.
|
||||
#
|
||||
209.157.86.2:/usr /usr nfs ro 0 0
|
||||
209.157.86.2:/var /var nfs ro 0 0
|
||||
proc /proc procfs rw 0 0
|
||||
@@ -1,34 +0,0 @@
|
||||
# DISKLESS RC.CONF.LOCAL
|
||||
#
|
||||
# Override system standard /etc/rc.conf
|
||||
|
||||
ldconfig_paths="$ldconfig_paths /usr/krb5/lib"
|
||||
ldconfig_paths_aout="$ldconfig_paths_aout /usr/krb5/lib/aout"
|
||||
|
||||
# Must do NFS mounts early
|
||||
# Must not attempt to mount root rw
|
||||
#
|
||||
early_nfs_mounts="YES"
|
||||
root_rw_mount="NO"
|
||||
|
||||
inetd_enable="NO"
|
||||
portmap_enable="NO"
|
||||
router_enable="NO"
|
||||
cron_enable="NO"
|
||||
sendmail_enable="NO"
|
||||
|
||||
# Enable additional services
|
||||
#
|
||||
|
||||
nfs_client_enable="YES"
|
||||
lpd_enable="YES"
|
||||
ntpdate_enable="YES"
|
||||
ntpdate_flags="apollo.backplane.com"
|
||||
xntpd_enable="YES"
|
||||
|
||||
if [ -f /etc/ipfw.conf ]; then
|
||||
firewall_enable="YES"
|
||||
firewall_type="/etc/ipfw.conf"
|
||||
firewall_quiet="NO"
|
||||
fi
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f /etc/rc.conf ]; then
|
||||
. /etc/rc.conf
|
||||
fi
|
||||
|
||||
# Firewall helper - if we configure the firewall to let through
|
||||
# ports > 4000, we need to configure the machines as such.
|
||||
#
|
||||
|
||||
sysctl -w net.inet.ip.portrange.first=4000
|
||||
|
||||
# Setup spool
|
||||
#
|
||||
|
||||
cat >> /var/spool/lpd/ljet4.ps << EOF
|
||||
#!/bin/sh
|
||||
#
|
||||
|
||||
gs -q -dSAFER -dNOPAUSE -sDEVICE=ljet4 -r600x600 -dBitsPerPixel=1 \
|
||||
-sOutputFile=- -
|
||||
EOF
|
||||
|
||||
chmod 755 /var/spool/lpd/ljet4.ps
|
||||
|
||||
mkdir /var/spool/ljet4
|
||||
chown daemon /var/spool/ljet4
|
||||
|
||||
# Setup remote source
|
||||
#
|
||||
|
||||
mount_mfs -s 600000 -T qp120at dummy /src
|
||||
mount apollo:/FreeBSD /FreeBSD
|
||||
mkdir /src/u3
|
||||
mkdir /src/u3/usr.obj
|
||||
|
||||
# Copy of ssh_host_key* files to where sshd
|
||||
# expects them, assuming you add to /usr/local/etc/sshd_config:
|
||||
#
|
||||
# HostKey /var/db/ssh_host_key
|
||||
#
|
||||
# Then restart sshd ( the /usr/local/etc/rc.d script installed by
|
||||
# the port probably failed due to the lack of host keys )
|
||||
|
||||
if [ -f /conf/ME/ssh_host_key ]; then
|
||||
cp /conf/ME/ssh_host_key* /var/db
|
||||
else
|
||||
(cd /var/db; ssh-keygen -f ssh_host_key -P "")
|
||||
fi
|
||||
chmod 400 /var/db/ssh_host_key
|
||||
chmod 644 /var/db/ssh_host_key.pub
|
||||
/usr/local/sbin/sshd
|
||||
|
||||
# Copy home directory so you can login
|
||||
#
|
||||
#
|
||||
|
||||
mount_mfs -s 65536 -T qp120at dummy /home
|
||||
|
||||
if [ -d /home.diskless ]; then
|
||||
cd /home.diskless
|
||||
for i in *; do
|
||||
if [ -f $i/home.tgz ]; then
|
||||
mkdir /home/$i
|
||||
chown $i /home/$i
|
||||
chmod 700 /home/$i
|
||||
(cd /home/$i; tar xzpf /home.diskless/$i/home.tgz)
|
||||
homeok=1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "${homeok:=0}" = "0" ]; then
|
||||
echo "ERROR, NO /home.diskless DIRECTORY TO COPY TO /HOME"
|
||||
sleep 10
|
||||
fi
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
*.err;kern.debug;auth.notice;mail.crit;lpr.info /dev/console
|
||||
*.err;kern.debug;auth.notice;mail.crit root
|
||||
*.emerg *
|
||||
@@ -1,52 +0,0 @@
|
||||
#
|
||||
# @(#)ttys 5.1 (Berkeley) 4/17/89
|
||||
#
|
||||
# name getty type status comments
|
||||
#
|
||||
# This entry needed for asking password when init goes to single-user mode
|
||||
# If you want to be asked for password, change "secure" to "insecure" here
|
||||
console none unknown off secure
|
||||
#
|
||||
ttyv0 "/usr/X11R6/bin/xdm -nodaemon -config /conf/209.157.86.6/xdm-config" cons25 on secure
|
||||
# Virtual terminals
|
||||
ttyv1 "/usr/libexec/getty Pc" cons25 on secure
|
||||
ttyv2 "/usr/libexec/getty Pc" cons25 on secure
|
||||
ttyv3 "/usr/libexec/getty Pc" cons25 on secure
|
||||
# Serial terminals
|
||||
ttyd0 "/usr/libexec/getty std.9600" unknown off secure
|
||||
ttyd1 "/usr/libexec/getty std.9600" unknown off secure
|
||||
ttyd2 "/usr/libexec/getty std.9600" unknown off secure
|
||||
ttyd3 "/usr/libexec/getty std.9600" unknown off secure
|
||||
# Pseudo terminals
|
||||
ttyp0 none network
|
||||
ttyp1 none network
|
||||
ttyp2 none network
|
||||
ttyp3 none network
|
||||
ttyp4 none network
|
||||
ttyp5 none network
|
||||
ttyp6 none network
|
||||
ttyp7 none network
|
||||
ttyp8 none network
|
||||
ttyp9 none network
|
||||
ttypa none network
|
||||
ttypb none network
|
||||
ttypc none network
|
||||
ttypd none network
|
||||
ttype none network
|
||||
ttypf none network
|
||||
ttypg none network
|
||||
ttyph none network
|
||||
ttypi none network
|
||||
ttypj none network
|
||||
ttypk none network
|
||||
ttypl none network
|
||||
ttypm none network
|
||||
ttypn none network
|
||||
ttypo none network
|
||||
ttypp none network
|
||||
ttypq none network
|
||||
ttypr none network
|
||||
ttyps none network
|
||||
ttypt none network
|
||||
ttypu none network
|
||||
ttypv none network
|
||||
@@ -1,15 +0,0 @@
|
||||
! $XConsortium: xdm-conf.cpp,v 1.2 93/09/28 14:30:32 gildea Exp $
|
||||
DisplayManager.errorLogFile: /var/run/xdm-errors
|
||||
DisplayManager.pidFile: /var/run/xdm-pid
|
||||
DisplayManager.servers: /usr/X11R6/lib/X11/xdm/Xservers-1
|
||||
DisplayManager.keyFile: /usr/X11R6/lib/X11/xdm/xdm-keys
|
||||
DisplayManager.servers: /usr/X11R6/lib/X11/xdm/Xservers
|
||||
DisplayManager.accessFile: /usr/X11R6/lib/X11/xdm/Xaccess
|
||||
DisplayManager._0.authorize: true
|
||||
DisplayManager._0.setup: /usr/X11R6/lib/X11/xdm/Xsetup_0
|
||||
DisplayManager._0.startup: /usr/X11R6/lib/X11/xdm/GiveConsole
|
||||
DisplayManager._0.reset: /usr/X11R6/lib/X11/xdm/TakeConsole
|
||||
DisplayManager*resources: /usr/X11R6/lib/X11/xdm/Xresources
|
||||
DisplayManager*session: /usr/X11R6/lib/X11/xdm/Xsession
|
||||
DisplayManager*authComplain: false
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#
|
||||
# @(#)aliases 5.3 (Berkeley) 5/24/90
|
||||
#
|
||||
# Aliases in this file will NOT be expanded in the header from
|
||||
# Mail, but WILL be visible over networks or from /bin/mail.
|
||||
#
|
||||
# >>>>>>>>>> The program "newaliases" must be run after
|
||||
# >> NOTE >> this file is updated for any changes to
|
||||
# >>>>>>>>>> show through to sendmail.
|
||||
#
|
||||
|
||||
# Basic system aliases -- these MUST be present
|
||||
MAILER-DAEMON: postmaster
|
||||
postmaster: root
|
||||
|
||||
# General redirections for pseudo accounts
|
||||
bin: root
|
||||
daemon: root
|
||||
games: root
|
||||
ingres: root
|
||||
nobody: root
|
||||
system: root
|
||||
toor: root
|
||||
uucp: root
|
||||
usenet: root
|
||||
root: [email protected]
|
||||
|
||||
diablo: dillon
|
||||
diablo-bugs: dillon
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# @(#)forward.map 1.1 1/17/95
|
||||
#
|
||||
# Put addresses to be forwarded here. Example:
|
||||
#
|
||||
# [email protected] [email protected]
|
||||
#
|
||||
@@ -1,11 +0,0 @@
|
||||
#
|
||||
# example:
|
||||
# fofs.com [email protected]
|
||||
#
|
||||
# NOTE: FORWARD.MAP can be used to override NDOMAIN.MAP for specific
|
||||
# users. NDOMAIN.MAP would then act as a catch-all
|
||||
#
|
||||
# NOTE: NDOMAIN.MAP only works to two levels. I.E. if you have an
|
||||
# entry for fubar.com, then [email protected] will work and
|
||||
# [email protected] will work, but NOT [email protected]
|
||||
#
|
||||
@@ -1,11 +0,0 @@
|
||||
*.err;kern.debug;auth.notice;mail.crit /dev/console
|
||||
# *.notice;kern.debug;lpr,auth.info;mail.crit /var/log/messages
|
||||
*.debug;kern.debug;lpr,auth.info;mail.crit;news.crit /var/log/messages
|
||||
mail.info /var/log/maillog
|
||||
news.info /var/log/news
|
||||
lpr.info /var/log/lpd-errs
|
||||
cron.* /var/log/cron
|
||||
#*.err root
|
||||
#*.notice;auth.debug root
|
||||
#*.alert root
|
||||
*.emerg *
|
||||
@@ -1,52 +0,0 @@
|
||||
#
|
||||
# @(#)ttys 5.1 (Berkeley) 4/17/89
|
||||
#
|
||||
# name getty type status comments
|
||||
#
|
||||
# This entry needed for asking password when init goes to single-user mode
|
||||
# If you want to be asked for password, change "secure" to "insecure" here
|
||||
console none unknown off secure
|
||||
#
|
||||
ttyv0 "/usr/libexec/getty Pc" cons25 on secure
|
||||
# Virtual terminals
|
||||
ttyv1 "/usr/libexec/getty Pc" cons25 on secure
|
||||
ttyv2 "/usr/libexec/getty Pc" cons25 on secure
|
||||
ttyv3 "/usr/libexec/getty Pc" cons25 on secure
|
||||
# Serial terminals
|
||||
ttyd0 "/usr/libexec/getty std.9600" unknown off secure
|
||||
ttyd1 "/usr/libexec/getty std.9600" unknown off secure
|
||||
ttyd2 "/usr/libexec/getty std.9600" unknown off secure
|
||||
ttyd3 "/usr/libexec/getty std.9600" unknown off secure
|
||||
# Pseudo terminals
|
||||
ttyp0 none network
|
||||
ttyp1 none network
|
||||
ttyp2 none network
|
||||
ttyp3 none network
|
||||
ttyp4 none network
|
||||
ttyp5 none network
|
||||
ttyp6 none network
|
||||
ttyp7 none network
|
||||
ttyp8 none network
|
||||
ttyp9 none network
|
||||
ttypa none network
|
||||
ttypb none network
|
||||
ttypc none network
|
||||
ttypd none network
|
||||
ttype none network
|
||||
ttypf none network
|
||||
ttypg none network
|
||||
ttyph none network
|
||||
ttypi none network
|
||||
ttypj none network
|
||||
ttypk none network
|
||||
ttypl none network
|
||||
ttypm none network
|
||||
ttypn none network
|
||||
ttypo none network
|
||||
ttypp none network
|
||||
ttypq none network
|
||||
ttypr none network
|
||||
ttyps none network
|
||||
ttypt none network
|
||||
ttypu none network
|
||||
ttypv none network
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
When templating, /conf/ME is typically a softlink to
|
||||
/conf/<appropriate-machine>. When doing a diskless boot, /conf/ME is
|
||||
retargeted by /etc/rc.diskless1 from pointing to the server to pointing
|
||||
to the client's directory, /conf/<ip-address-of-client>. The retargeting
|
||||
is accomplished through an MFS -o union mount.
|
||||
|
||||
When templating, this softlink should be different for each machine.
|
||||
When doing a diskless boot, this softlink is typically part of the / NFS
|
||||
mount from the server and points to the server's conf directory, but gets
|
||||
retargeted during the /etc/rc.diskless1 phase.
|
||||
|
||||
System-wide configuration files must generally be targeted through /conf/ME.
|
||||
For example, your /etc/rc.conf.local should become a softlink to
|
||||
/conf/ME/rc.conf.local and your real rc.conf.local should go into the
|
||||
appropriate /conf/<appropriate-machine> directory. This is also true of
|
||||
/etc/rc.local, /etc/fstab, /etc/syslog.conf, /etc/ccd.conf, /etc/ipfw.conf,
|
||||
/etc/motd, /etc/resolv.conf, and possibly even /etc/ttys ( if you want
|
||||
to start an X session up on boot on certain of your machines ).
|
||||
|
||||
When templating, you duplicate your / and /usr partitions on each machine's
|
||||
local disk from a single master ( assuming /var and /home reside elsewhere ),
|
||||
EXCEPT for the /conf/ME softlink. The /conf/ME softlink is the only thing
|
||||
on / that should be different for each machine.
|
||||
|
||||
There are often categories of configuration files. For example, all of your
|
||||
shell machines may use one resolv.conf while all of your mail proxies may
|
||||
use another. Configuration files can be categorized fairly easily through
|
||||
/conf/HT.<category> directories. You put the actual configuration file in
|
||||
/conf/HT.<category> and make a softlink from
|
||||
/conf/ME/<appropriate-machines>/config-file to "../HT.<category/config-file".
|
||||
This means that access to these files tends to run through more then one
|
||||
softlink. The advantage is that for all the complexity of your /conf
|
||||
directory hierarchy, most of your common config files exist in only one place
|
||||
in reality.
|
||||
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
|
||||
BOOTP configuration mechanism
|
||||
|
||||
Matthew Dillon
|
||||
[email protected]
|
||||
|
||||
BOOTP kernels automatically configure the machine's IP address, netmask,
|
||||
optional NFS based swap, and NFS based root mount. The NFS server will
|
||||
typically export a shared read-only /, /usr, and /var to any number of
|
||||
workstations. The shared read-only root is typically either the server's
|
||||
own root or, if you are more security concious, a contrived root.
|
||||
|
||||
The key issue with starting up a BOOTP kernel is that you typically want
|
||||
to export read-only NFS partitions from the server, yet still be able to
|
||||
customize each workstation ( or not ).
|
||||
|
||||
/etc/rc.diskless1 is responsible for doing core mounts and for retargeting
|
||||
/conf/ME ( part of the read-only root NFS mount ) to /conf/$IP_OF_CLIENT.
|
||||
/etc/rc.conf.local and /etc/rc.local, along with other machine-specific
|
||||
configuration files, are typically softlinks to /conf/ME/<filename>.
|
||||
|
||||
In the BOOTP workstation /conf/$IP/rc.conf.local, you must typically
|
||||
turn *OFF* most of the system option defaults in /etc/rc.conf as well
|
||||
as do additional custom configuration of your environment
|
||||
|
||||
The /usr/src/share/examples/diskless directory contains a typical
|
||||
X session / sshd based workstation configuration. The directories
|
||||
involved are HT.DISKLESS/ and 192.157.86.12/.
|
||||
|
||||
Essentially, the $IP/ directory ( which rc.diskless looks for in
|
||||
/conf/$IP/ ) contains all the junk. The HT.DISKLESS directory exists
|
||||
to hold common elements of your custom configuration so you do not have
|
||||
to repeat those elements for each workstation. The example /conf
|
||||
structure included here shows how to create a working sshd setup ( so
|
||||
you can sshd into the diskless workstation ), retarget xdm's pid and error
|
||||
files to R+W directories if /usr is mounted read-only, and retarget
|
||||
syslogd and other programs. This example is not designed to run out of
|
||||
the box and some modifications are required.
|
||||
|
||||
>> NOTE << HT.DISKLESS/ttys contains the typical configuration required
|
||||
to bring X up at boot time. Essentially, it runs xdm in the foreground
|
||||
with the appropriate arguments rather then a getty on ttyv0. You must
|
||||
run xdm on ttyv0 in order to prevent xdm racing with getty on a virtual
|
||||
terminal. Such a race can cause your keyboard to be directed away from
|
||||
the X session, essentially making the session unusable.
|
||||
|
||||
Typically you should start with a clean slate by tar-copying this example
|
||||
directory to /conf and then hack on it in /conf rather then in
|
||||
/usr/share/examples/diskless.
|
||||
|
||||
BOOTP CLIENT SETUP
|
||||
|
||||
Here is a typical kernel configuration. If you have only one ethernet
|
||||
interface you do not need to wire BOOTP to a specific interface name.
|
||||
BOOTP requires NFS and NFS_ROOT, and our boot scripts require MFS. If
|
||||
your /tmp is *not* a softlink to /var/tmp, the scripts also require NULLFS
|
||||
|
||||
# BootP
|
||||
#
|
||||
options BOOTP # Use BOOTP to obtain IP address/hostname
|
||||
options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info
|
||||
options "BOOTP_NFSV3" # Use NFS v3 to NFS mount rootoptions
|
||||
options BOOTP_COMPAT # Workaround for broken bootp daemons.
|
||||
#options "BOOTP_WIRED_TO=de0"
|
||||
|
||||
options MFS # Memory File System
|
||||
options NFS # Network Filesystem
|
||||
options NFS_ROOT # Nfs can be root
|
||||
options NULLFS # nullfs to map /var/tmp to /tmp
|
||||
|
||||
BOOTP SERVER SETUP
|
||||
|
||||
The BOOTP server must be running on the same logical LAN as the the
|
||||
BOOTP client(s). You need to setup two things:
|
||||
|
||||
(1) You need to NFS-export /, /usr, and /var.
|
||||
|
||||
(2) You need to run a BOOTP server. DHCPD can do this.
|
||||
|
||||
|
||||
NFS Export:
|
||||
|
||||
Here is an example "/etc/exports" file.
|
||||
|
||||
/ -ro -maproot=root: -network 192.157.86.0 -mask 255.255.255.192
|
||||
/usr -ro -maproot=root: -network 192.157.86.0 -mask 255.255.255.192
|
||||
/var -ro -maproot=root: -network 192.157.86.0 -mask 255.255.255.192
|
||||
|
||||
In order to be an NFS server, the server must run portmap, mountd,
|
||||
nfsd, and rpc.statd. The standard NFS server options in /etc/rc.conf
|
||||
will work ( you should put your overrides in /etc/rc.conf.local on the
|
||||
server and not edit the distribution /etc/rc.conf, though ).
|
||||
|
||||
BOOTP Server:
|
||||
|
||||
This configuration file "/etc/dhcpd.conf" example is for
|
||||
the '/usr/ports/net/isc-dhcp' dhcpd port.
|
||||
|
||||
subnet 192.157.86.0 netmask 255.255.255.192 {
|
||||
# range if you want to run the core dhcpd service of
|
||||
# dynamic IP assignment, but it is not used with BOOTP
|
||||
# workstations
|
||||
range 192.157.86.32 192.157.86.62;
|
||||
|
||||
# misc configuration.
|
||||
#
|
||||
option routers 192.157.86.2;
|
||||
option domain-name-servers 192.157.86.2;
|
||||
|
||||
server-name "apollo.fubar.com";
|
||||
option subnet-mask 255.255.255.192;
|
||||
option domain-name-servers 192.157.86.2;
|
||||
option domain-name "fubar.com";
|
||||
option broadcast-address 192.157.86.63;
|
||||
option routers 192.157.86.2;
|
||||
}
|
||||
|
||||
host test1 {
|
||||
hardware ethernet 00:a0:c9:d3:38:25;
|
||||
fixed-address 192.157.86.11;
|
||||
option root-path "192.157.86.2:/";
|
||||
option option-128 "192.157.86.2:/images/swap";
|
||||
}
|
||||
|
||||
host test2 {
|
||||
# hardware ethernet 00:e0:29:1d:16:09;
|
||||
hardware ethernet 00:10:5a:a8:94:0e;
|
||||
fixed-address 192.157.86.12;
|
||||
option root-path "192.157.86.2:/";
|
||||
option option-128 "192.157.86.2:/images/swap";
|
||||
}
|
||||
|
||||
SWAP. This example includes options to automatically BOOTP configure
|
||||
NFS swap on each workstation. In order to use this capabilities you
|
||||
need to NFS-export a swap directory READ+WRITE to the workstations.
|
||||
|
||||
You must then create a swap directory for each workstation you wish to
|
||||
assign swap to. In this example I created a dummy user 'lander' and
|
||||
did an NFS export of /images/swap enforcing a UID of 'lander' for
|
||||
all accesses.
|
||||
|
||||
apollo:/usr/ports/net# ls -la /images/swap
|
||||
total 491786
|
||||
drwxr-xr-x 2 root wheel 512 Dec 28 07:00 .
|
||||
drwxr-xr-x 8 root wheel 512 Jan 20 10:54 ..
|
||||
-rw-r--r-- 1 lander wheel 33554432 Dec 23 14:35 swap.192.157.86.11
|
||||
-rw-r--r-- 1 lander wheel 335544320 Jan 24 16:55 swap.192.157.86.12
|
||||
-rw-r--r-- 1 lander wheel 134217728 Jan 21 17:19 swap.192.157.86.6
|
||||
|
||||
A swap file is best created with dd:
|
||||
|
||||
# create a 32MB swap file for a BOOTP workstation
|
||||
dd if=/dev/zero of=swap.IPADDRESS bs=1m count=32
|
||||
|
||||
It is generally a good idea to give your workstations some swap space,
|
||||
but not a requirement if they have a lot of memory.
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
|
||||
TEMPLATING machine configurations
|
||||
|
||||
Matthew Dillon
|
||||
[email protected]
|
||||
|
||||
This document describes a general mechanism by which you can template
|
||||
/ and /usr. That is, to keep a 'master template' of / and /usr on a
|
||||
separate machine which is then used to update the rest of your machines.
|
||||
|
||||
Generally speaking, you can't simply mirror /. You might be able to
|
||||
get away with mirroring /usr. There are two main problems involved with
|
||||
templating:
|
||||
|
||||
(1) Avoiding overwriting run-time generated files
|
||||
|
||||
By default, the system maintains a number of files in the root
|
||||
partition. For example, sendmail will dbm /etc/aliases into
|
||||
/etc/aliases.db. vipw or chpass or other password related routines
|
||||
will regenerate the password dbm's /etc/spwd.db, /etc/pwd.db, and
|
||||
passwd. /etc/namedb/s might contain generated secondaries. And
|
||||
so forth.
|
||||
|
||||
The templating mechanism must avoid copying over such files.
|
||||
|
||||
(2) Customizing machines.
|
||||
|
||||
Customizing machines is actually considerably simpler. You create
|
||||
a configuration hierarchy and convert the configuration files that
|
||||
have to be customized into softlinks that run through a special
|
||||
softlink in the configuration directory. This will work for every
|
||||
configuration file except possibly /etc/master.passwd
|
||||
|
||||
For example, /etc/resolv.conf would be turned into a softlink to
|
||||
/conf/ME/resolv.conf, and /conf/ME itself would be a softlink to
|
||||
/conf/<HOSTNAME>. The actual resolv.conf configuration file
|
||||
would reside in /conf/<HOSTNAME>.
|
||||
|
||||
If you have a lot of hosts, some configuration files may be commonly
|
||||
classified. For example, all your shell machines might have the
|
||||
same /etc/resolv.conf. The solution is to make
|
||||
/conf/<HOSTNAME>/resolv.conf a softlink to a common directory, say
|
||||
/conf/HT.SHELL/resolv.conf. It may sound a little messy, but this
|
||||
sort of categorization actually makes the sysadmins job much, much
|
||||
easier.
|
||||
|
||||
The /conf/ directory hierarchy is stored on the template and
|
||||
distributed to all the machines along with the rest of the root
|
||||
partition.
|
||||
|
||||
This type of customization is taken from my direct experience
|
||||
instituting such a system at BEST. At the time, BEST had over 45
|
||||
machines managed from a single template.
|
||||
|
||||
RUN-TIME GENERATED OR MODIFIED FILES IN / or /USR
|
||||
|
||||
/etc/aliases.db
|
||||
/etc/master.passwd
|
||||
/etc/spwd.db
|
||||
/etc/pwd.db
|
||||
/etc/passwd
|
||||
/etc/namedb/s
|
||||
/root/.history
|
||||
/root/.ssh/identity
|
||||
/root/.ssh/identity.pub
|
||||
/root/.ssh/random_seed
|
||||
/root/.ssh/known_hosts
|
||||
/conf/ME
|
||||
/kernel* ( note 2 )
|
||||
/dev ( note 3 )
|
||||
/var ( note 4 )
|
||||
/home ( note 4 )
|
||||
/lost+found
|
||||
|
||||
/usr/lost+found
|
||||
/usr/home ( note 4 )
|
||||
/usr/crash ( note 5 )
|
||||
/usr/obj ( note 5 )
|
||||
/usr/ports ( note 5 )
|
||||
/usr/src ( note 5 )
|
||||
/usr/local/crack ( note 5 )
|
||||
/usr/X11R6/lib/X11/xdm/xdm-errors ( note 6 )
|
||||
/usr/X11R6/lib/X11/xdm/xdm-pid ( note 6 )
|
||||
/usr/local/etc/ssh_host_key ( note 6 )
|
||||
/usr/local/etc/ssh_host_key.pub ( note 6 )
|
||||
/usr/local/etc/ssh_random_seed ( note 6 )
|
||||
|
||||
/conf/ME ( note 7 )
|
||||
|
||||
note 2: You typically want to update kernels manually and *NOT*
|
||||
template them as a safety measure. This also allows you to run
|
||||
different kernels on different machines or.
|
||||
|
||||
note 3: /dev must be updated manually. Some devices, such as tty's and
|
||||
pty's, use the access and/or modify time and/or user/group
|
||||
operationally and regenerating the devices on the fly would be
|
||||
bad.
|
||||
|
||||
note 4: /var and /home are usually separately mounted partitions and
|
||||
thus would not fall under the template, but as a safety measure
|
||||
the template copier refuse to copy directories named 'home'.
|
||||
|
||||
note 5: These are directories that are as often created directly on
|
||||
/usr as they are separately-mounted partitions. You typically
|
||||
do not want to template such directories.
|
||||
|
||||
note 6: Note that you can solve the problem of xdm and sshd creating
|
||||
files in /usr. With xdm, edit /usr/X11R6/lib/xdm/xdm-config
|
||||
and change the errorLogFile and pidFile config lines.
|
||||
|
||||
With sshd, add 'HostKey' and 'RandomSeed' directives to specify
|
||||
/var/db for the location of the host key and run-time sshd
|
||||
random seed:
|
||||
|
||||
HostKey /var/db/ssh_host_key
|
||||
RandomSeed /var/db/ssh_random_seed
|
||||
|
||||
note 7: In this example, /conf/ME is the machine customizer and must
|
||||
be pointed to the /conf/<full-host-name>/ directory, which is
|
||||
different for each machine. Thus, the /conf/ME softlink
|
||||
should never be overwritten by the templating copy.
|
||||
|
||||
|
||||
TYPICAL CUSTOMIZED CONFIGRATION SOFTLINKS
|
||||
|
||||
The following files typically need to be turned into softlinks
|
||||
to /conf/ME/<filename>:
|
||||
|
||||
/etc/ccd.conf -> /conf/ME/ccd.conf
|
||||
/etc/ipfw.conf ...
|
||||
/etc/fstab
|
||||
/etc/motd
|
||||
/etc/resolv.conf
|
||||
/etc/aliases
|
||||
/etc/sendmail.cw
|
||||
/etc/organization
|
||||
/etc/named.conf
|
||||
/etc/rc.conf.local
|
||||
/etc/printcap
|
||||
/etc/inetd.conf
|
||||
/etc/login.conf
|
||||
/etc/gettytab
|
||||
/etc/ntp.conf
|
||||
/etc/exports
|
||||
/root/.k5login -> /conf/ME/root/.k5login
|
||||
|
||||
And, of course, /conf/ME is usually a softlink to the appropriate
|
||||
/conf/<full-host-name>/. Depending on your system configuration,
|
||||
there may be other files not listed above that you have to worry about.
|
||||
|
||||
In many cases, /conf/ME/filename is itself a softlink to
|
||||
"../HT.xxxx/filename", where HT.xxxx is something like HT.STD ... this
|
||||
added complexity actually makes it easier to manage multiple
|
||||
classifications of machines.
|
||||
|
||||
DELETION OF FILES
|
||||
|
||||
Any file found on the template destination that does not exist in the
|
||||
source and is not listed as an exception by the source should be deleted.
|
||||
However, deletion can be dangerous and cpdup will ask for confirmation
|
||||
by default. Once you know you aren't going to blow things up, you can
|
||||
turn this feature off and update your systems automatically from cron.
|
||||
|
||||
By formalizing the delete operation, you can be 100% sure that it is
|
||||
possible to recreate / and /usr on any machine with only the original
|
||||
template and a backup of the ( relatively few ) explicitly-excepted
|
||||
files. The most common mistake a sysop makes is to make a change to a
|
||||
file in / or /usr on a target machine instead of the template machine.
|
||||
If the target machine is updated once a night from cron, the sysop
|
||||
quickly learns not to do this ( because his changes get overwritten
|
||||
overnight ). With a manual update, these sorts of mistakes can propogate
|
||||
for weeks or months before they are caught.
|
||||
|
||||
TEMPLATE COPYING AND SAFETY
|
||||
THE CPDUP PROGRAM
|
||||
|
||||
The 'cpdup' program is a program which efficiently duplicates a directory
|
||||
tree. The program copies source to destination, duplicating devices,
|
||||
softlinks, hardlinks, files, modification times, uid, gid, flags, perms,
|
||||
and so forth. The program incorporates several major features:
|
||||
|
||||
* The program refuses, absolutely, to cross partition boundries.
|
||||
i.e. if you were copying the template /usr from an NFS mount to
|
||||
your /usr, and you had a mount point called /usr/home, the
|
||||
template copying program would *NOT* descend into /usr/home on
|
||||
the destination.
|
||||
|
||||
This is a safety.
|
||||
|
||||
* The program accesses a file called .cpignore in each directory
|
||||
it descending into on the source to obtain a list of exceptions
|
||||
for that directory -- that is, files not to copy or mess with.
|
||||
|
||||
This is a templating function.
|
||||
|
||||
* The program refuses to delete a directory on the destination
|
||||
being replaced by a softlink or file on the source.
|
||||
|
||||
This is a safety mechanism
|
||||
|
||||
* The program is capable of maintaing MD5 check cache files and
|
||||
doing an MD5 check between source and destination during the
|
||||
scan.
|
||||
|
||||
* The program is capable of deleting files/directories on the
|
||||
destination that do not exist on the source, but asks for
|
||||
confirmation by default.
|
||||
|
||||
This is a templating and a safety mechanism.
|
||||
|
||||
* The program uses a copy-to-tmp-and-rename methodology allowing
|
||||
it to be used to update live filesystems.
|
||||
|
||||
This is a templating mechanism.
|
||||
|
||||
* The program, by default, tries to determine if a copy is required
|
||||
by checking modify times, file size, perms, and other stat
|
||||
elements. If the elements match, it does not bother to copy
|
||||
( unless an MD5 check is being made, in which case it must read
|
||||
the destination file ).
|
||||
|
||||
You typically run cpdup on the target machine. The target machine
|
||||
temporarily mounts the template machine's / and /usr via NFS, read-only,
|
||||
and runs cpdup to update / and /usr. If you use this methodology note
|
||||
that THERE ARE SECURITY CONSIDERATIONS! See 'SECURITY CONSIDERATIONS WITH
|
||||
NFS' below.
|
||||
|
||||
Whatever script you use that does the NFS mounts should ensure that the
|
||||
mount succeeded before continuing with the cpdup.
|
||||
|
||||
You should create .cpignore files in the appropriate directories on the
|
||||
template machine's / and /usr partitions so as not to overwrite active
|
||||
files on the target. The most critical .cpignore files should be
|
||||
protected with 'chflags schg .cpignore'. Specifically, the ones in /
|
||||
and /etc, but possibly others as well. For example, the .cpignore
|
||||
hierarchy for protect /root is:
|
||||
|
||||
# /root/.cpignore contains
|
||||
.history
|
||||
|
||||
# /root/.ssh/.cpignore contains
|
||||
random_seed
|
||||
known_hosts
|
||||
authorized_keys
|
||||
identity
|
||||
identity.pub
|
||||
|
||||
WHEN INITIALLY CONVERTING A TARGET MACHINE TO USE TEMPLATING, ALWAYS
|
||||
MAKE A FULL BACKUP OF THE TARGET MACHINE FIRST! You may accidently delete
|
||||
files on the target during the conversion due to forgetting to enter
|
||||
items into appropriate .cpignore files on the source.
|
||||
|
||||
SECURITY CONSIDERATIONS WITH NFS ROOT EXPORT FROM TEMPLATE MACHINE
|
||||
SECURITY CONSIDERATIONS WITH NFS USR EXPORT FROM TEMPLATE MACHINE
|
||||
|
||||
There are some serious security considerations that must be taken into
|
||||
account when exporting / and /usr on the template machine.
|
||||
|
||||
* only export read-only
|
||||
|
||||
* the password file ( aka vipw ) may not contain any crypted passwords
|
||||
at all. You MUST use ssh or kerberos to access the template machine.
|
||||
|
||||
You can get away with giving only root a crypted password, but only
|
||||
if you disallow network root logins and only allow direct root
|
||||
logins on the console.
|
||||
|
||||
* The machine's private ssh_host_key usually resides in /usr/local/etc.
|
||||
You must move this key to /var/db. You can softlink link so no
|
||||
modification of sshd_config is required.
|
||||
|
||||
* The machine's private ~root/.ssh/identity file is also exposed by
|
||||
the NFS export, you should move this file to /var/db as well and
|
||||
put a softlink in ~root/.ssh.
|
||||
|
||||
* DON'T EXPORT /var ! Either that, or don't put the private keys
|
||||
in /var/db ... put them somewhere else.
|
||||
|
||||
* You may want to redirect the location of the random_seed file, which
|
||||
can be done by editing ~root/.ssh/sshd_config and
|
||||
/usr/local/etc/sshd_config so it is not exposed either.
|
||||
|
||||
-Matt
|
||||
Matthew Dillon
|
||||
[email protected]
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#########################################################################
|
||||
#
|
||||
# Example of ppp.linkdown file
|
||||
#
|
||||
# This file is checked when ppp closes a connection.
|
||||
# ppp searches the labels in this file as follows:
|
||||
#
|
||||
# 1) The label that matches the IP number assigned to our side.
|
||||
#
|
||||
# 2) The label specified on the command line to ppp.
|
||||
#
|
||||
# 3) If no label has been found, use MYADDR if it exists.
|
||||
#
|
||||
#
|
||||
# $Id: ppp.linkdown.sample,v 1.2 1998/11/05 23:14:19 brian Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
# We don't really need to do much here. If we have notified a DNS
|
||||
# of our temporary IP number, we may want to ``un-notify'' them.
|
||||
#
|
||||
# If you're into sound effects when the link goes down, you can run
|
||||
# ``auplay'' (assuming NAS is installed and configured).
|
||||
#
|
||||
MYADDR:
|
||||
!bg /usr/X11R6/bin/auplay /etc/ppp/linkdown.au
|
||||
|
||||
# If you're running ``ppp -auto -alias dynamic-alias-auto'', and are
|
||||
# assigned a dynamic IP number by the peer, this may be worth while
|
||||
# to keep the interface aliases to a minimum (see ``enable iface-alias''
|
||||
# in the man page):
|
||||
#
|
||||
dynamic-alias-auto:
|
||||
iface clear
|
||||
@@ -1,49 +0,0 @@
|
||||
#########################################################################
|
||||
#
|
||||
# Example of ppp.linkup file
|
||||
#
|
||||
# This file is checked when ppp establishes a connection.
|
||||
# ppp searches the labels in this file as follows:
|
||||
#
|
||||
# 1) The label that matches the IP number assigned to our side.
|
||||
#
|
||||
# 2) The label specified on the command line to ppp.
|
||||
#
|
||||
# 3) If no label has been found, use MYADDR if it exists.
|
||||
#
|
||||
#
|
||||
# $Id: ppp.linkup.sample,v 1.14 1998/05/21 21:45:47 brian Exp $
|
||||
#
|
||||
#########################################################################
|
||||
|
||||
# It is no longer necessary to re-add the default route here as our
|
||||
# ppp.conf route is `sticky' (see the man page).
|
||||
# If you're into sound effects when the link comes up, you can run
|
||||
# ``auplay'' (assuming NAS is installed and configured).
|
||||
#
|
||||
MYADDR:
|
||||
!bg /usr/X11R6/bin/auplay /etc/ppp/linkup.au
|
||||
|
||||
# If we've got 192.244.176.32 as our address, then regard peer as a gateway
|
||||
# to 192.244.176.0 network. This may also be done in ppp.conf instead.
|
||||
#
|
||||
192.244.176.32:
|
||||
add 192.244.176.0 0 HISADDR
|
||||
|
||||
#You may want to execute a script after connecting. This script can do
|
||||
# nice things such as kick off "sendmail -q", "popclient my.isp" and
|
||||
# "slurp -d news". It can be passed MYADDR, HISADDR and INTERFACE
|
||||
# as arguments too - useful for informing a DNS of your assigned IP.
|
||||
#
|
||||
# You may also want some sound effects....
|
||||
#
|
||||
pmdemand:
|
||||
!bg /etc/ppp/ppp.etherup.pmdemand
|
||||
! sh -c "cat /etc/ppp/linkup.au >/dev/audio"
|
||||
|
||||
# If your minimum call charge is 5 minutes, you may as well stay on
|
||||
# the line for that amount of time. If we want a 60 second subsequent
|
||||
# timeout, set your timeout to 300 in ppp.conf and then do this:
|
||||
#
|
||||
min5minutes:
|
||||
!bg sh -c "sleep 240; pppctl -p mypassword 3000 set timeout 60"
|
||||
@@ -1,41 +0,0 @@
|
||||
##################################################
|
||||
#
|
||||
# Example of ppp.secret file
|
||||
#
|
||||
# This file is used to authenticate incoming connections.
|
||||
# You must ``enable'' either PAP or CHAP in your ppp.conf file.
|
||||
# The peer may then use any of the Authname/Authkey pairs listed.
|
||||
# Additionally, if ``passwdauth'' is enabled and an entry isn't
|
||||
# found in this file, the passwd(5) database is used.
|
||||
#
|
||||
# If the password is specified as "*", look it up in passwd(5).
|
||||
# This doesn't work for CHAP connections as ppp must have access
|
||||
# to the unencrypted password for CHAP.
|
||||
#
|
||||
# If an IP address or address range is given as the third field, it
|
||||
# will be assigned to the peer. A ``*'' or an empty field may be
|
||||
# used as a placeholder if you do not wish to override the IP
|
||||
# address, but wish to specify further fields.
|
||||
#
|
||||
# If a label is given as the forth field, it is used when reading
|
||||
# the ppp.linkup and ppp.linkdown files. A ``*'' or an empty field
|
||||
# can be used as a placeholder if you do not wish to override the
|
||||
# label, but wish to specify further fields.
|
||||
#
|
||||
# If a phone number or list of phone numbers is given as the fifth
|
||||
# field, these numbers will be used to call back the client if
|
||||
# ``auth'' or ``cbcp'' callback is enabled (see ``set callback'').
|
||||
# A ``*'' specifies that the client must specify the number.
|
||||
#
|
||||
# $Id: ppp.secret.sample,v 1.8 1998/08/07 18:44:31 brian Exp $
|
||||
#
|
||||
##################################################
|
||||
|
||||
# Authname Authkey Peer's IP address Label Callback
|
||||
|
||||
oscar OurSecretKey 192.2.18.34
|
||||
BigBird X4dWg9327 192.2.18.33/32
|
||||
fred * * fred
|
||||
subnet * 192.2.18.35-192.2.18.70 subnet
|
||||
admin * * * *
|
||||
homeworker * * * 1234567
|
||||
@@ -1,320 +0,0 @@
|
||||
Introduction
|
||||
|
||||
This package constitutes the alpha distribution of the soft update
|
||||
code updates for the fast filesystem.
|
||||
|
||||
For More information on what Soft Updates is, see:
|
||||
http://www.ece.cmu.edu/~ganger/papers/CSE-TR-254-95/
|
||||
|
||||
Status
|
||||
|
||||
My `filesystem torture tests' (described below) run for days without
|
||||
a hitch (no panic's, hangs, filesystem corruption, or memory leaks).
|
||||
However, I have had several panic's reported to me by folks that
|
||||
are field testing the code which I have not yet been able to
|
||||
reproduce or fix. Although these panic's are rare and do not cause
|
||||
filesystem corruption, the code should only be put into production
|
||||
on systems where the system administrator is aware that it is being
|
||||
run, and knows how to turn it off if problems arise. Thus, you may
|
||||
hand out this code to others, but please ensure that this status
|
||||
message is included with any distributions. Please also include
|
||||
the file ffs_softdep.stub.c in any distributions so that folks that
|
||||
cannot abide by the need to redistribute source will not be left
|
||||
with a kernel that will not link. It will resolve all the calls
|
||||
into the soft update code and simply ignores the request to enable
|
||||
them. Thus you will be able to ensure that your other hooks have
|
||||
not broken anything and that your kernel is softdep-ready for those
|
||||
that wish to use them. Please report problems back to me with
|
||||
kernel backtraces of panics if possible. This is massively complex
|
||||
code, and people only have to have their filesystems hosed once or
|
||||
twice to avoid future changes like the plague. I want to find and
|
||||
fix as many bugs as soon as possible so as to get the code rock
|
||||
solid before it gets widely released. Please report any bugs that
|
||||
you uncover to [email protected].
|
||||
|
||||
Performance
|
||||
|
||||
Running the Andrew Benchmarks yields the following raw data:
|
||||
|
||||
Phase Normal Softdep What it does
|
||||
1 3s <1s Creating directories
|
||||
2 8s 4s Copying files
|
||||
3 6s 6s Recursive directory stats
|
||||
4 8s 9s Scanning each file
|
||||
5 25s 25s Compilation
|
||||
|
||||
Normal: 19.9u 29.2s 0:52.8 135+630io
|
||||
Softdep: 20.3u 28.5s 0:47.8 103+363io
|
||||
|
||||
Another interesting datapoint are my `filesystem torture tests'.
|
||||
They consist of 1000 runs of the andrew benchmarks, 1000 copy and
|
||||
removes of /etc with randomly selected pauses of 0-60 seconds
|
||||
between each copy and remove, and 500 find from / with randomly
|
||||
selected pauses of 100 seconds between each run). The run of the
|
||||
torture test compares as follows:
|
||||
|
||||
With soft updates: writes: 6 sync, 1,113,686 async; run time 19hr, 50min
|
||||
Normal filesystem: writes: 1,459,147 sync, 487,031 async; run time 27hr, 15min
|
||||
|
||||
The upshot is 42% less I/O and 28% shorter running time.
|
||||
|
||||
Another interesting test point is a full MAKEDEV. Because it runs
|
||||
as a shell script, it becomes mostly limited by the execution speed
|
||||
of the machine on which it runs. Here are the numbers:
|
||||
|
||||
With soft updates:
|
||||
|
||||
labrat# time ./MAKEDEV std
|
||||
2.2u 32.6s 0:34.82 100.0% 0+0k 11+36io 0pf+0w
|
||||
|
||||
labrat# ls | wc
|
||||
522 522 3317
|
||||
|
||||
Without soft updates:
|
||||
|
||||
labrat# time ./MAKEDEV std
|
||||
2.0u 40.5s 0:42.53 100.0% 0+0k 11+1221io 0pf+0w
|
||||
|
||||
labrat# ls | wc
|
||||
522 522 3317
|
||||
|
||||
Of course, some of the system time is being pushed
|
||||
to the syncer process, but that is a different story.
|
||||
|
||||
To show a benchmark designed to highlight the soft update code
|
||||
consider a tar of zero-sized files and an rm -rf of a directory tree
|
||||
that has at least 50 files or so at each level. Running a test with
|
||||
a directory tree containing 28 directories holding 202 empty files
|
||||
produces the following numbers:
|
||||
|
||||
With soft updates:
|
||||
tar: 0.0u 0.5s 0:00.65 76.9% 0+0k 0+44io 0pf+0w (0 sync, 33 async writes)
|
||||
rm: 0.0u 0.2s 0:00.20 100.0% 0+0k 0+37io 0pf+0w (0 sync, 72 async writes)
|
||||
|
||||
Normal filesystem:
|
||||
tar: 0.0u 1.1s 0:07.27 16.5% 0+0k 60+586io 0pf+0w (523 sync, 0 async writes)
|
||||
rm: 0.0u 0.5s 0:01.84 29.3% 0+0k 0+318io 0pf+0w (258 sync, 65 async writes)
|
||||
|
||||
The large reduction in writes is because inodes are clustered, so
|
||||
most of a block gets allocated, then the whole block is written
|
||||
out once rather than having the same block written once for each
|
||||
inode allocated from it. Similarly each directory block is written
|
||||
once rather than once for each new directory entry. Effectively
|
||||
what the update code is doing is allocating a bunch of inodes
|
||||
and directory entries without writing anything, then ensuring that
|
||||
the block containing the inodes is written first followed by the
|
||||
directory block that references them. If there were data in the
|
||||
files it would further ensure that the data blocks were written
|
||||
before their inodes claimed them.
|
||||
|
||||
Copyright Restrictions
|
||||
|
||||
Please familiarize yourself with the copyright restrictions
|
||||
contained at the top of either the sys/ufs/ffs/softdep.h or
|
||||
sys/ufs/ffs/ffs_softdep.c file. The key provision is similar
|
||||
to the one used by the DB 2.0 package and goes as follows:
|
||||
|
||||
Redistributions in any form must be accompanied by information
|
||||
on how to obtain complete source code for any accompanying
|
||||
software that uses the this software. This source code must
|
||||
either be included in the distribution or be available for
|
||||
no more than the cost of distribution plus a nominal fee,
|
||||
and must be freely redistributable under reasonable
|
||||
conditions. For an executable file, complete source code
|
||||
means the source code for all modules it contains. It does
|
||||
not mean source code for modules or files that typically
|
||||
accompany the operating system on which the executable file
|
||||
runs, e.g., standard library modules or system header files.
|
||||
|
||||
The idea is to allow those of you freely redistributing your source
|
||||
to use it while retaining for myself the right to peddle it for
|
||||
money to the commercial UNIX vendors. Note that I have included a
|
||||
stub file ffs_softdep.c.stub that is freely redistributable so that
|
||||
you can put in all the necessary hooks to run the full soft updates
|
||||
code, but still allow vendors that want to maintain proprietary
|
||||
source to have a working system. I do plan to release the code with
|
||||
a `Berkeley style' copyright once I have peddled it around to the
|
||||
commercial vendors. If you have concerns about this copyright,
|
||||
feel free to contact me with them and we can try to resolve any
|
||||
difficulties.
|
||||
|
||||
Soft Dependency Operation
|
||||
|
||||
The soft update implementation does NOT require ANY changes
|
||||
to the on-disk format of your filesystems. Furthermore it is
|
||||
not used by default for any filesystems. It must be enabled on
|
||||
a filesystem by filesystem basis by running tunefs to set a
|
||||
bit in the superblock indicating that the filesystem should be
|
||||
managed using soft updates. If you wish to stop using
|
||||
soft updates due to performance or reliability reasons,
|
||||
you can simply run tunefs on it again to turn off the bit and
|
||||
revert to normal operation. The additional dynamic memory load
|
||||
placed on the kernel malloc arena is approximately equal to
|
||||
the amount of memory used by vnodes plus inodes (for a system
|
||||
with 1000 vnodes, the additional peak memory load is about 300K).
|
||||
|
||||
Kernel Changes
|
||||
|
||||
There are two new changes to the kernel functionality that are not
|
||||
contained in in the soft update files. The first is a `trickle
|
||||
sync' facility running in the kernel as process 3. This trickle
|
||||
sync process replaces the traditional `update' program (which should
|
||||
be commented out of the /etc/rc startup script). When a vnode is
|
||||
first written it is placed 30 seconds down on the trickle sync
|
||||
queue. If it still exists and has dirty data when it reaches the
|
||||
top of the queue, it is sync'ed. This approach evens out the load
|
||||
on the underlying I/O system and avoids writing short-lived files.
|
||||
The papers on trickle-sync tend to favor aging based on buffers
|
||||
rather than files. However, I sync on file age rather than buffer
|
||||
age because the data structures are much smaller as there are
|
||||
typically far fewer files than buffers. Although this can make the
|
||||
I/O spikey when a big file times out, it is still much better than
|
||||
the wholesale sync's that were happening before. It also adapts
|
||||
much better to the soft update code where I want to control
|
||||
aging to improve performance (inodes age in 10 seconds, directories
|
||||
in 15 seconds, files in 30 seconds). This ensures that most
|
||||
dependencies are gone (e.g., inodes are written when directory
|
||||
entries want to go to disk) reducing the amount of rollback that
|
||||
is needed.
|
||||
|
||||
The other main kernel change is to split the vnode freelist into
|
||||
two separate lists. One for vnodes that are still being used to
|
||||
identify buffers and the other for those vnodes no longer identifying
|
||||
any buffers. The latter list is used by getnewvnode in preference
|
||||
to the former.
|
||||
|
||||
Packaging of Kernel Changes
|
||||
|
||||
The sys subdirectory contains the changes and additions to the
|
||||
kernel. My goal in writing this code was to minimize the changes
|
||||
that need to be made to the kernel. Thus, most of the new code
|
||||
is contained in the two new files softdep.h and ffs_softdep.c.
|
||||
The rest of the kernel changes are simply inserting hooks to
|
||||
call into these two new files. Although there has been some
|
||||
structural reorganization of the filesystem code to accommodate
|
||||
gathering the information required by the soft update code,
|
||||
the actual ordering of filesystem operations when soft updates
|
||||
are disabled is unchanged.
|
||||
|
||||
The kernel changes are packaged as a set of diffs. As I am
|
||||
doing my development in BSD/OS, the diffs are relative to the
|
||||
BSD/OS versions of the files. Because BSD/OS recently had
|
||||
4.4BSD-Lite2 merged into it, the Lite2 files are a good starting
|
||||
point for figuring out the changes. There are 40 files that
|
||||
require change plus the two new files. Most of these files have
|
||||
only a few lines of changes in them. However, four files have
|
||||
fairly extensive changes: kern/vfs_subr.c, ufs/ufs/ufs_lookup.c,
|
||||
ufs/ufs/ufs_vnops.c, and ufs/ffs/ffs_alloc.c. For these four
|
||||
files, I have provided the original Lite2 version, the Lite2
|
||||
version with the diffs merged in, and the diffs between the
|
||||
BSD/OS and merged version. Even so, I expect that there will
|
||||
be some difficulty in doing the merge; I am certainly willing
|
||||
to assist in helping get the code merged into your system.
|
||||
|
||||
Packaging of Utility Changes
|
||||
|
||||
The utilities subdirectory contains the changes and additions
|
||||
to the utilities. There are diffs to three utilities enclosed:
|
||||
|
||||
tunefs - add a flag to enable and disable soft updates
|
||||
|
||||
mount - print out whether soft updates are enabled and
|
||||
also statistics on number of sync and async writes
|
||||
|
||||
fsck - tighter checks on acceptable errors and a slightly
|
||||
different policy for what to put in lost+found on
|
||||
filesystems using soft updates
|
||||
|
||||
In addition you should recompile vmstat so as to get reports
|
||||
on the 13 new memory types used by the soft update code.
|
||||
It is not necessary to use the new version of fsck, however it
|
||||
would aid in my debugging if you do. Also, because of the time
|
||||
lag between deleting a directory entry and the inode it
|
||||
references, you will find a lot more files showing up in your
|
||||
lost+found if you do not use the new version. Note that the
|
||||
new version checks for the soft update flag in the superblock
|
||||
and only uses the new algorithms if it is set. So, it will run
|
||||
unchanged on the filesystems that are not using soft updates.
|
||||
|
||||
Operation
|
||||
|
||||
Once you have booted a kernel that incorporates the soft update
|
||||
code and installed the updated utilities, do the following:
|
||||
|
||||
1) Comment out the update program in /etc/rc.
|
||||
|
||||
2) Run `tunefs -n enable' on one or more test filesystems.
|
||||
|
||||
3) Mount these filesystems and then type `mount' to ensure that
|
||||
they have been enabled for soft updates.
|
||||
|
||||
4) Copy the test directory to a softdep filesystem, chdir into
|
||||
it and run `./doit'. You may want to check out each of the
|
||||
three subtests individually first: doit1 - andrew benchmarks,
|
||||
doit2 - copy and removal of /etc, doit3 - find from /.
|
||||
|
||||
====
|
||||
Additional notes from Feb 13
|
||||
|
||||
hen removing huge directories of files, it is possible to get
|
||||
the incore state arbitrarily far ahead of the disk. Maintaining
|
||||
all the associated depedency information can exhaust the kernel
|
||||
malloc arena. To avoid this senario, I have put some limits on
|
||||
the soft update code so that it will not be allowed to rampage
|
||||
through all of the kernel memory. I enclose below the relevant
|
||||
patches to vnode.h and vfs_subr.c (which allow the soft update
|
||||
code to speed up the filesystem syncer process). I have also
|
||||
included the diffs for ffs_softdep.c. I hope to make a pass over
|
||||
ffs_softdep.c to isolate the differences with my standard version
|
||||
so that these diffs are less painful to incorporate.
|
||||
|
||||
Since I know you like to play with tuning, I have put the relevant
|
||||
knobs on sysctl debug variables. The tuning knobs can be viewed
|
||||
with `sysctl debug' and set with `sysctl -w debug.<name>=value'.
|
||||
The knobs are as follows:
|
||||
|
||||
debug.max_softdeps - limit on any given resource
|
||||
debug.tickdelay - ticks to delay before allocating
|
||||
debug.max_limit_hit - number of times tickdelay imposed
|
||||
debug.rush_requests - number of rush requests to filesystem syncer
|
||||
|
||||
The max_softdeps limit is derived from vnodesdesired which in
|
||||
turn is sized based on the amount of memory on the machine.
|
||||
When the limit is hit, a process requesting a resource first
|
||||
tries to speed up the filesystem syncer process. Such a
|
||||
request is recorded as a rush_request. After syncdelay / 2
|
||||
unserviced rush requests (typically 15) are in the filesystem
|
||||
syncers queue (i.e., it is more than 15 seconds behind in its
|
||||
work), the process requesting the memory is put to sleep for
|
||||
tickdelay seconds. Such a delay is recorded in max_limit_hit.
|
||||
Following this delay it is granted its memory without further
|
||||
delay. I have tried the following experiments in which I
|
||||
delete an MH directory containing 16,703 files:
|
||||
|
||||
Run # 1 2 3
|
||||
|
||||
max_softdeps 4496 4496 4496
|
||||
tickdelay 100 == 1 sec 20 == 0.2 sec 2 == 0.02 sec
|
||||
max_limit_hit 16 == 16 sec 27 == 5.4 sec 203 == 4.1 sec
|
||||
rush_requests 147 102 93
|
||||
run time 57 sec 46 sec 45 sec
|
||||
I/O's 781 859 936
|
||||
|
||||
When run with no limits, it completes in 40 seconds. So, the
|
||||
time spent in delay is directly added to the bottom line.
|
||||
Shortening the tick delay does cut down the total running time,
|
||||
but at the expense of generating more total I/O operations
|
||||
due to the rush orders being sent to the filesystem syncer.
|
||||
Although the number of rush orders decreases with a shorter
|
||||
tick delay, there are more requests in each order, hence the
|
||||
increase in I/O count. Also, although the I/O count does rise
|
||||
with a shorter delay, it is still at least an order of magnitude
|
||||
less than without soft updates. Anyway, you may want to play
|
||||
around with these value to see what works best and to see if
|
||||
you can get an insight into how best to tune them. If you get
|
||||
out of memory panic's, then you have max_softdeps set too high.
|
||||
The max_limit_hit and rush_requests show be reset to zero
|
||||
before each run. The minimum legal value for tickdelay is 2
|
||||
(if you set it below that, the code will use 2).
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# $Id: Makefile,v 1.1 1999/01/02 01:12:19 semen Exp $
|
||||
|
||||
.PATH: ${.CURDIR}/../../ntfs
|
||||
KMOD= ntfs
|
||||
SRCS= ntfs_vfsops.c ntfs_vnops.c ntfs_subr.c ntfs_ihash.c \
|
||||
ntfs_compr.c opt_vmpage.h
|
||||
NOMAN=
|
||||
VFS_KLD=
|
||||
CFLAGS+= -DNTFS
|
||||
CLEANFILES= opt_vmpage.h
|
||||
|
||||
opt_vmpage.h:
|
||||
touch ${.TARGET}
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
@@ -1,320 +0,0 @@
|
||||
Introduction
|
||||
|
||||
This package constitutes the alpha distribution of the soft update
|
||||
code updates for the fast filesystem.
|
||||
|
||||
For More information on what Soft Updates is, see:
|
||||
http://www.ece.cmu.edu/~ganger/papers/CSE-TR-254-95/
|
||||
|
||||
Status
|
||||
|
||||
My `filesystem torture tests' (described below) run for days without
|
||||
a hitch (no panic's, hangs, filesystem corruption, or memory leaks).
|
||||
However, I have had several panic's reported to me by folks that
|
||||
are field testing the code which I have not yet been able to
|
||||
reproduce or fix. Although these panic's are rare and do not cause
|
||||
filesystem corruption, the code should only be put into production
|
||||
on systems where the system administrator is aware that it is being
|
||||
run, and knows how to turn it off if problems arise. Thus, you may
|
||||
hand out this code to others, but please ensure that this status
|
||||
message is included with any distributions. Please also include
|
||||
the file ffs_softdep.stub.c in any distributions so that folks that
|
||||
cannot abide by the need to redistribute source will not be left
|
||||
with a kernel that will not link. It will resolve all the calls
|
||||
into the soft update code and simply ignores the request to enable
|
||||
them. Thus you will be able to ensure that your other hooks have
|
||||
not broken anything and that your kernel is softdep-ready for those
|
||||
that wish to use them. Please report problems back to me with
|
||||
kernel backtraces of panics if possible. This is massively complex
|
||||
code, and people only have to have their filesystems hosed once or
|
||||
twice to avoid future changes like the plague. I want to find and
|
||||
fix as many bugs as soon as possible so as to get the code rock
|
||||
solid before it gets widely released. Please report any bugs that
|
||||
you uncover to [email protected].
|
||||
|
||||
Performance
|
||||
|
||||
Running the Andrew Benchmarks yields the following raw data:
|
||||
|
||||
Phase Normal Softdep What it does
|
||||
1 3s <1s Creating directories
|
||||
2 8s 4s Copying files
|
||||
3 6s 6s Recursive directory stats
|
||||
4 8s 9s Scanning each file
|
||||
5 25s 25s Compilation
|
||||
|
||||
Normal: 19.9u 29.2s 0:52.8 135+630io
|
||||
Softdep: 20.3u 28.5s 0:47.8 103+363io
|
||||
|
||||
Another interesting datapoint are my `filesystem torture tests'.
|
||||
They consist of 1000 runs of the andrew benchmarks, 1000 copy and
|
||||
removes of /etc with randomly selected pauses of 0-60 seconds
|
||||
between each copy and remove, and 500 find from / with randomly
|
||||
selected pauses of 100 seconds between each run). The run of the
|
||||
torture test compares as follows:
|
||||
|
||||
With soft updates: writes: 6 sync, 1,113,686 async; run time 19hr, 50min
|
||||
Normal filesystem: writes: 1,459,147 sync, 487,031 async; run time 27hr, 15min
|
||||
|
||||
The upshot is 42% less I/O and 28% shorter running time.
|
||||
|
||||
Another interesting test point is a full MAKEDEV. Because it runs
|
||||
as a shell script, it becomes mostly limited by the execution speed
|
||||
of the machine on which it runs. Here are the numbers:
|
||||
|
||||
With soft updates:
|
||||
|
||||
labrat# time ./MAKEDEV std
|
||||
2.2u 32.6s 0:34.82 100.0% 0+0k 11+36io 0pf+0w
|
||||
|
||||
labrat# ls | wc
|
||||
522 522 3317
|
||||
|
||||
Without soft updates:
|
||||
|
||||
labrat# time ./MAKEDEV std
|
||||
2.0u 40.5s 0:42.53 100.0% 0+0k 11+1221io 0pf+0w
|
||||
|
||||
labrat# ls | wc
|
||||
522 522 3317
|
||||
|
||||
Of course, some of the system time is being pushed
|
||||
to the syncer process, but that is a different story.
|
||||
|
||||
To show a benchmark designed to highlight the soft update code
|
||||
consider a tar of zero-sized files and an rm -rf of a directory tree
|
||||
that has at least 50 files or so at each level. Running a test with
|
||||
a directory tree containing 28 directories holding 202 empty files
|
||||
produces the following numbers:
|
||||
|
||||
With soft updates:
|
||||
tar: 0.0u 0.5s 0:00.65 76.9% 0+0k 0+44io 0pf+0w (0 sync, 33 async writes)
|
||||
rm: 0.0u 0.2s 0:00.20 100.0% 0+0k 0+37io 0pf+0w (0 sync, 72 async writes)
|
||||
|
||||
Normal filesystem:
|
||||
tar: 0.0u 1.1s 0:07.27 16.5% 0+0k 60+586io 0pf+0w (523 sync, 0 async writes)
|
||||
rm: 0.0u 0.5s 0:01.84 29.3% 0+0k 0+318io 0pf+0w (258 sync, 65 async writes)
|
||||
|
||||
The large reduction in writes is because inodes are clustered, so
|
||||
most of a block gets allocated, then the whole block is written
|
||||
out once rather than having the same block written once for each
|
||||
inode allocated from it. Similarly each directory block is written
|
||||
once rather than once for each new directory entry. Effectively
|
||||
what the update code is doing is allocating a bunch of inodes
|
||||
and directory entries without writing anything, then ensuring that
|
||||
the block containing the inodes is written first followed by the
|
||||
directory block that references them. If there were data in the
|
||||
files it would further ensure that the data blocks were written
|
||||
before their inodes claimed them.
|
||||
|
||||
Copyright Restrictions
|
||||
|
||||
Please familiarize yourself with the copyright restrictions
|
||||
contained at the top of either the sys/ufs/ffs/softdep.h or
|
||||
sys/ufs/ffs/ffs_softdep.c file. The key provision is similar
|
||||
to the one used by the DB 2.0 package and goes as follows:
|
||||
|
||||
Redistributions in any form must be accompanied by information
|
||||
on how to obtain complete source code for any accompanying
|
||||
software that uses the this software. This source code must
|
||||
either be included in the distribution or be available for
|
||||
no more than the cost of distribution plus a nominal fee,
|
||||
and must be freely redistributable under reasonable
|
||||
conditions. For an executable file, complete source code
|
||||
means the source code for all modules it contains. It does
|
||||
not mean source code for modules or files that typically
|
||||
accompany the operating system on which the executable file
|
||||
runs, e.g., standard library modules or system header files.
|
||||
|
||||
The idea is to allow those of you freely redistributing your source
|
||||
to use it while retaining for myself the right to peddle it for
|
||||
money to the commercial UNIX vendors. Note that I have included a
|
||||
stub file ffs_softdep.c.stub that is freely redistributable so that
|
||||
you can put in all the necessary hooks to run the full soft updates
|
||||
code, but still allow vendors that want to maintain proprietary
|
||||
source to have a working system. I do plan to release the code with
|
||||
a `Berkeley style' copyright once I have peddled it around to the
|
||||
commercial vendors. If you have concerns about this copyright,
|
||||
feel free to contact me with them and we can try to resolve any
|
||||
difficulties.
|
||||
|
||||
Soft Dependency Operation
|
||||
|
||||
The soft update implementation does NOT require ANY changes
|
||||
to the on-disk format of your filesystems. Furthermore it is
|
||||
not used by default for any filesystems. It must be enabled on
|
||||
a filesystem by filesystem basis by running tunefs to set a
|
||||
bit in the superblock indicating that the filesystem should be
|
||||
managed using soft updates. If you wish to stop using
|
||||
soft updates due to performance or reliability reasons,
|
||||
you can simply run tunefs on it again to turn off the bit and
|
||||
revert to normal operation. The additional dynamic memory load
|
||||
placed on the kernel malloc arena is approximately equal to
|
||||
the amount of memory used by vnodes plus inodes (for a system
|
||||
with 1000 vnodes, the additional peak memory load is about 300K).
|
||||
|
||||
Kernel Changes
|
||||
|
||||
There are two new changes to the kernel functionality that are not
|
||||
contained in in the soft update files. The first is a `trickle
|
||||
sync' facility running in the kernel as process 3. This trickle
|
||||
sync process replaces the traditional `update' program (which should
|
||||
be commented out of the /etc/rc startup script). When a vnode is
|
||||
first written it is placed 30 seconds down on the trickle sync
|
||||
queue. If it still exists and has dirty data when it reaches the
|
||||
top of the queue, it is sync'ed. This approach evens out the load
|
||||
on the underlying I/O system and avoids writing short-lived files.
|
||||
The papers on trickle-sync tend to favor aging based on buffers
|
||||
rather than files. However, I sync on file age rather than buffer
|
||||
age because the data structures are much smaller as there are
|
||||
typically far fewer files than buffers. Although this can make the
|
||||
I/O spikey when a big file times out, it is still much better than
|
||||
the wholesale sync's that were happening before. It also adapts
|
||||
much better to the soft update code where I want to control
|
||||
aging to improve performance (inodes age in 10 seconds, directories
|
||||
in 15 seconds, files in 30 seconds). This ensures that most
|
||||
dependencies are gone (e.g., inodes are written when directory
|
||||
entries want to go to disk) reducing the amount of rollback that
|
||||
is needed.
|
||||
|
||||
The other main kernel change is to split the vnode freelist into
|
||||
two separate lists. One for vnodes that are still being used to
|
||||
identify buffers and the other for those vnodes no longer identifying
|
||||
any buffers. The latter list is used by getnewvnode in preference
|
||||
to the former.
|
||||
|
||||
Packaging of Kernel Changes
|
||||
|
||||
The sys subdirectory contains the changes and additions to the
|
||||
kernel. My goal in writing this code was to minimize the changes
|
||||
that need to be made to the kernel. Thus, most of the new code
|
||||
is contained in the two new files softdep.h and ffs_softdep.c.
|
||||
The rest of the kernel changes are simply inserting hooks to
|
||||
call into these two new files. Although there has been some
|
||||
structural reorganization of the filesystem code to accommodate
|
||||
gathering the information required by the soft update code,
|
||||
the actual ordering of filesystem operations when soft updates
|
||||
are disabled is unchanged.
|
||||
|
||||
The kernel changes are packaged as a set of diffs. As I am
|
||||
doing my development in BSD/OS, the diffs are relative to the
|
||||
BSD/OS versions of the files. Because BSD/OS recently had
|
||||
4.4BSD-Lite2 merged into it, the Lite2 files are a good starting
|
||||
point for figuring out the changes. There are 40 files that
|
||||
require change plus the two new files. Most of these files have
|
||||
only a few lines of changes in them. However, four files have
|
||||
fairly extensive changes: kern/vfs_subr.c, ufs/ufs/ufs_lookup.c,
|
||||
ufs/ufs/ufs_vnops.c, and ufs/ffs/ffs_alloc.c. For these four
|
||||
files, I have provided the original Lite2 version, the Lite2
|
||||
version with the diffs merged in, and the diffs between the
|
||||
BSD/OS and merged version. Even so, I expect that there will
|
||||
be some difficulty in doing the merge; I am certainly willing
|
||||
to assist in helping get the code merged into your system.
|
||||
|
||||
Packaging of Utility Changes
|
||||
|
||||
The utilities subdirectory contains the changes and additions
|
||||
to the utilities. There are diffs to three utilities enclosed:
|
||||
|
||||
tunefs - add a flag to enable and disable soft updates
|
||||
|
||||
mount - print out whether soft updates are enabled and
|
||||
also statistics on number of sync and async writes
|
||||
|
||||
fsck - tighter checks on acceptable errors and a slightly
|
||||
different policy for what to put in lost+found on
|
||||
filesystems using soft updates
|
||||
|
||||
In addition you should recompile vmstat so as to get reports
|
||||
on the 13 new memory types used by the soft update code.
|
||||
It is not necessary to use the new version of fsck, however it
|
||||
would aid in my debugging if you do. Also, because of the time
|
||||
lag between deleting a directory entry and the inode it
|
||||
references, you will find a lot more files showing up in your
|
||||
lost+found if you do not use the new version. Note that the
|
||||
new version checks for the soft update flag in the superblock
|
||||
and only uses the new algorithms if it is set. So, it will run
|
||||
unchanged on the filesystems that are not using soft updates.
|
||||
|
||||
Operation
|
||||
|
||||
Once you have booted a kernel that incorporates the soft update
|
||||
code and installed the updated utilities, do the following:
|
||||
|
||||
1) Comment out the update program in /etc/rc.
|
||||
|
||||
2) Run `tunefs -n enable' on one or more test filesystems.
|
||||
|
||||
3) Mount these filesystems and then type `mount' to ensure that
|
||||
they have been enabled for soft updates.
|
||||
|
||||
4) Copy the test directory to a softdep filesystem, chdir into
|
||||
it and run `./doit'. You may want to check out each of the
|
||||
three subtests individually first: doit1 - andrew benchmarks,
|
||||
doit2 - copy and removal of /etc, doit3 - find from /.
|
||||
|
||||
====
|
||||
Additional notes from Feb 13
|
||||
|
||||
hen removing huge directories of files, it is possible to get
|
||||
the incore state arbitrarily far ahead of the disk. Maintaining
|
||||
all the associated depedency information can exhaust the kernel
|
||||
malloc arena. To avoid this senario, I have put some limits on
|
||||
the soft update code so that it will not be allowed to rampage
|
||||
through all of the kernel memory. I enclose below the relevant
|
||||
patches to vnode.h and vfs_subr.c (which allow the soft update
|
||||
code to speed up the filesystem syncer process). I have also
|
||||
included the diffs for ffs_softdep.c. I hope to make a pass over
|
||||
ffs_softdep.c to isolate the differences with my standard version
|
||||
so that these diffs are less painful to incorporate.
|
||||
|
||||
Since I know you like to play with tuning, I have put the relevant
|
||||
knobs on sysctl debug variables. The tuning knobs can be viewed
|
||||
with `sysctl debug' and set with `sysctl -w debug.<name>=value'.
|
||||
The knobs are as follows:
|
||||
|
||||
debug.max_softdeps - limit on any given resource
|
||||
debug.tickdelay - ticks to delay before allocating
|
||||
debug.max_limit_hit - number of times tickdelay imposed
|
||||
debug.rush_requests - number of rush requests to filesystem syncer
|
||||
|
||||
The max_softdeps limit is derived from vnodesdesired which in
|
||||
turn is sized based on the amount of memory on the machine.
|
||||
When the limit is hit, a process requesting a resource first
|
||||
tries to speed up the filesystem syncer process. Such a
|
||||
request is recorded as a rush_request. After syncdelay / 2
|
||||
unserviced rush requests (typically 15) are in the filesystem
|
||||
syncers queue (i.e., it is more than 15 seconds behind in its
|
||||
work), the process requesting the memory is put to sleep for
|
||||
tickdelay seconds. Such a delay is recorded in max_limit_hit.
|
||||
Following this delay it is granted its memory without further
|
||||
delay. I have tried the following experiments in which I
|
||||
delete an MH directory containing 16,703 files:
|
||||
|
||||
Run # 1 2 3
|
||||
|
||||
max_softdeps 4496 4496 4496
|
||||
tickdelay 100 == 1 sec 20 == 0.2 sec 2 == 0.02 sec
|
||||
max_limit_hit 16 == 16 sec 27 == 5.4 sec 203 == 4.1 sec
|
||||
rush_requests 147 102 93
|
||||
run time 57 sec 46 sec 45 sec
|
||||
I/O's 781 859 936
|
||||
|
||||
When run with no limits, it completes in 40 seconds. So, the
|
||||
time spent in delay is directly added to the bottom line.
|
||||
Shortening the tick delay does cut down the total running time,
|
||||
but at the expense of generating more total I/O operations
|
||||
due to the rush orders being sent to the filesystem syncer.
|
||||
Although the number of rush orders decreases with a shorter
|
||||
tick delay, there are more requests in each order, hence the
|
||||
increase in I/O count. Also, although the I/O count does rise
|
||||
with a shorter delay, it is still at least an order of magnitude
|
||||
less than without soft updates. Anyway, you may want to play
|
||||
around with these value to see what works best and to see if
|
||||
you can get an insight into how best to tune them. If you get
|
||||
out of memory panic's, then you have max_softdeps set too high.
|
||||
The max_limit_hit and rush_requests show be reset to zero
|
||||
before each run. The minimum legal value for tickdelay is 2
|
||||
(if you set it below that, the code will use 2).
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
# Espan~ol (backward compatible with ASCII)
|
||||
#
|
||||
# $Id: es_ES.DIS_8859-15.src,v 1.3 1997/02/22 19:54:35 peter Exp $
|
||||
#
|
||||
charmap map.DIS_8859-15
|
||||
order \
|
||||
# controls
|
||||
<NU>;...;<US>;<PA>;...;<AC>;\
|
||||
#
|
||||
<NS>;<SP>;!;<!I>;\";<<<>;</>/>>;<Nb>;\
|
||||
<Eu>;<Ct>;<DO>;<Pd>;<Ye>;\
|
||||
%;&;';\(;\);*;+;<+->;<-:>;<*X>;\,;<-->;-;.;/;\
|
||||
# digits
|
||||
0;(1,<1S>);(2,<2S>);(3,<3S>);4;...;9;\
|
||||
#
|
||||
:;\;;\<;=;>;?;<?I>;<SE>;<PI>;<Co>;<Rg>;<At>;\
|
||||
# capital
|
||||
(A,<A'>,<A!>,<A/>>,<AA>,<A:>,<A?>,<AE>);\
|
||||
B;(C,<C,>);{CH,Ch};D;(E,<E'>,<E!>,<E/>>,<E:>);\
|
||||
F;G;H;(I,<I'>,<I!>,<I/>>,<I:>);\
|
||||
J;...;K;L;{LL,Ll};M;(N,<N?>);(O,<O'>,<O!>,<O/>>,<O:>,<O?>,<O//>,<OE>);\
|
||||
P;Q;R;{RR,Rr};(S,<S<>);T;(U,<U'>,<U!>,<U/>>,<U:>);\
|
||||
V;W;X;(Y,<Y'>,<Y:>);(Z,<Z<>);\
|
||||
<D->;<TH>;\
|
||||
#
|
||||
[;\\;];^;_;<'m>;`;\
|
||||
# small
|
||||
(a,<a'>,<a!>,<a/>>,<aa>,<a:>,<a?>,<ae>);\
|
||||
b;(c,<c,>);ch;d;(e,<e'>,<e!>,<e/>>,<e:>);\
|
||||
f;g;h;(i,<i'>,<i!>,<i/>>,<i:>);\
|
||||
j;...;k;l;ll;m;(n,<n?>);(o,<o'>,<o!>,<o/>>,<o:>,<o?>,<o//>,<oe>);\
|
||||
p;q;r;rr;(s,<s<>);t;(u,<u'>,<u!>,<u/>>,<u:>);\
|
||||
v;w;x;(y,<y'>,<y:>);(z,<z<>);\
|
||||
<d->;<th>;<ss>;\
|
||||
#
|
||||
\{;<NO>;|;\};~;<.M>;<DG>;<My>;<DT>;\
|
||||
# remains
|
||||
<-a>;<-o>
|
||||
@@ -1,38 +0,0 @@
|
||||
# icelandic (backward compatible with ASCII)
|
||||
#
|
||||
# $Id: is_IS.DIS_8859-15.src,v 1.4 1997/02/22 19:54:38 peter Exp $
|
||||
#
|
||||
charmap map.DIS_8859-15
|
||||
order \
|
||||
# controls
|
||||
<NU>;...;<US>;<PA>;...;<AC>;\
|
||||
#
|
||||
<NS>;<SP>;!;<!I>;\";<<<>;</>/>>;<Nb>;\
|
||||
<Eu>;<Ct>;<DO>;<Pd>;<Ye>;\
|
||||
%;&;';\(;\);*;+;<+->;<-:>;<*X>;\,;<-->;-;.;/;\
|
||||
# digits
|
||||
0;(1,<1S>);(2,<2S>);(3,<3S>);4;...;9;\
|
||||
#
|
||||
:;\;;\<;=;>;?;<?I>;<SE>;<PI>;<Co>;<Rg>;<At>;\
|
||||
# capital
|
||||
(A,<A'>,<A!>,<A/>>,<AA>,<A:>,<A?>);\
|
||||
B;(C,<C,>);(D,<D->);(E,<E'>,<E!>,<E/>>,<E:>);\
|
||||
F;G;H;(I,<I'>,<I!>,<I/>>,<I:>);\
|
||||
J;...;M;(N,<N?>);(O,<O'>,<O!>,<O/>>,<O?>,<O//>,<OE>);\
|
||||
P;...;R;(S,<S<>);T;(U,<U'>,<U!>,<U/>>,<U:>);\
|
||||
V;W;X;(Y,<Y'>,<Y:>);(Z,<Z<>);\
|
||||
<TH>;<AE>;<O:>;\
|
||||
#
|
||||
[;\\;];^;_;<'m>;`;\
|
||||
# small
|
||||
(a,<a'>,<a!>,<a/>>,<aa>,<a:>,<a?>);\
|
||||
b;(c,<c,>);(d,<d->);(e,<e'>,<e!>,<e/>>,<e:>);\
|
||||
f;g;h;(i,<i'>,<i!>,<i/>>,<i:>);\
|
||||
j;...;m;(n,<n?>);(o,<o'>,<o!>,<o/>>,<o?>,<o//>,<oe>);\
|
||||
p;...;r;(s,<s<>);t;(u,<u'>,<u!>,<u/>>,<u:>);\
|
||||
v;w;x;(y,<y'>,<y:>);(z,<z<>);\
|
||||
<th>;<ae>;<o:>;<ss>;\
|
||||
#
|
||||
\{;<NO>;|;\};~;<.M>;<DG>;<My>;<DT>;\
|
||||
# remains
|
||||
<-a>;<-o>
|
||||
@@ -1,38 +0,0 @@
|
||||
# latin1 (backward compatible with ASCII)
|
||||
#
|
||||
# $Id: lt_LN.DIS_8859-15.src,v 1.8 1997/02/22 19:54:39 peter Exp $
|
||||
#
|
||||
charmap map.DIS_8859-15
|
||||
order \
|
||||
# controls
|
||||
<NU>;...;<US>;<PA>;...;<AC>;\
|
||||
#
|
||||
<NS>;<SP>;!;<!I>;\";<<<>;</>/>>;<Nb>;\
|
||||
<Eu>;<Ct>;<DO>;<Pd>;<Ye>;\
|
||||
%;&;';\(;\);*;+;<+->;<-:>;<*X>;\,;<-->;-;.;/;\
|
||||
# digits
|
||||
0;(1,<1S>);(2,<2S>);(3,<3S>);4;...;9;\
|
||||
#
|
||||
:;\;;\<;=;>;?;<?I>;<SE>;<PI>;<Co>;<Rg>;<At>;\
|
||||
# capital
|
||||
(A,<A'>,<A!>,<A/>>,<AA>,<A:>,<A?>,<AE>);\
|
||||
B;(C,<C,>);D;(E,<E'>,<E!>,<E/>>,<E:>);\
|
||||
F;G;H;(I,<I'>,<I!>,<I/>>,<I:>);\
|
||||
J;...;M;(N,<N?>);(O,<O'>,<O!>,<O/>>,<O:>,<O?>,<O//>,<OE>);\
|
||||
P;...;R;(S,<S<>);T;(U,<U'>,<U!>,<U/>>,<U:>);\
|
||||
V;W;X;(Y,<Y'>,<Y:>);(Z,<Z<>);\
|
||||
<D->;<TH>;\
|
||||
#
|
||||
[;\\;];^;_;<'m>;`;\
|
||||
# small
|
||||
(a,<a'>,<a!>,<a/>>,<aa>,<a:>,<a?>,<ae>);\
|
||||
b;(c,<c,>);d;(e,<e'>,<e!>,<e/>>,<e:>);\
|
||||
f;g;h;(i,<i'>,<i!>,<i/>>,<i:>);\
|
||||
j;...;m;(n,<n?>);(o,<o'>,<o!>,<o/>>,<o:>,<o?>,<o//>,<oe>);\
|
||||
p;...;r;(s,<s<>);t;(u,<u'>,<u!>,<u/>>,<u:>);\
|
||||
v;w;x;(y,<y'>,<y:>);(z,<z<>);\
|
||||
<d->;<th>;<ss>;\
|
||||
#
|
||||
\{;<NO>;|;\};~;<.M>;<DG>;<My>;<DT>;\
|
||||
# remains
|
||||
<-a>;<-o>
|
||||
@@ -1,174 +0,0 @@
|
||||
NU \x00
|
||||
SH \x01
|
||||
SX \x02
|
||||
EX \x03
|
||||
ET \x04
|
||||
EQ \x05
|
||||
AK \x06
|
||||
BL \x07
|
||||
BS \x08
|
||||
HT \x09
|
||||
LF \x0a
|
||||
VT \x0b
|
||||
FF \x0c
|
||||
CR \x0d
|
||||
SO \x0e
|
||||
SI \x0f
|
||||
DL \x10
|
||||
D1 \x11
|
||||
D2 \x12
|
||||
D3 \x13
|
||||
D4 \x14
|
||||
NK \x15
|
||||
SY \x16
|
||||
EB \x17
|
||||
CN \x18
|
||||
EM \x19
|
||||
SB \x1a
|
||||
EC \x1b
|
||||
FS \x1c
|
||||
GS \x1d
|
||||
RS \x1e
|
||||
US \x1f
|
||||
SP \x20
|
||||
Nb \x23
|
||||
DO \x24
|
||||
At \x40
|
||||
<( \x5b
|
||||
// \x5c
|
||||
)> \x5d
|
||||
'> \x5e
|
||||
'! \x60
|
||||
(! \x7b
|
||||
!! \x7c
|
||||
!) \x7d
|
||||
'? \x7e
|
||||
DT \x7f
|
||||
PA \x80
|
||||
HO \x81
|
||||
BH \x82
|
||||
NH \x83
|
||||
IN \x84
|
||||
NL \x85
|
||||
SA \x86
|
||||
ES \x87
|
||||
HS \x88
|
||||
HJ \x89
|
||||
VS \x8a
|
||||
PD \x8b
|
||||
PU \x8c
|
||||
RI \x8d
|
||||
S2 \x8e
|
||||
S3 \x8f
|
||||
DC \x90
|
||||
P1 \x91
|
||||
P2 \x92
|
||||
TS \x93
|
||||
CC \x94
|
||||
MW \x95
|
||||
SG \x96
|
||||
EG \x97
|
||||
SS \x98
|
||||
GC \x99
|
||||
SC \x9a
|
||||
CI \x9b
|
||||
ST \x9c
|
||||
OC \x9d
|
||||
PM \x9e
|
||||
AC \x9f
|
||||
NS \xa0
|
||||
!I \xa1
|
||||
Ct \xa2
|
||||
Pd \xa3
|
||||
Eu \xa4
|
||||
Ye \xa5
|
||||
S< \xa6
|
||||
SE \xa7
|
||||
s< \xa8
|
||||
Co \xa9
|
||||
-a \xaa
|
||||
<< \xab
|
||||
NO \xac
|
||||
-- \xad
|
||||
Rg \xae
|
||||
'm \xaf
|
||||
DG \xb0
|
||||
+- \xb1
|
||||
2S \xb2
|
||||
3S \xb3
|
||||
Z< \xb4
|
||||
My \xb5
|
||||
PI \xb6
|
||||
.M \xb7
|
||||
z< \xb8
|
||||
1S \xb9
|
||||
-o \xba
|
||||
>> \xbb
|
||||
OE \xbc
|
||||
oe \xbd
|
||||
Y: \xbe
|
||||
?I \xbf
|
||||
A! \xc0
|
||||
A' \xc1
|
||||
A> \xc2
|
||||
A? \xc3
|
||||
A: \xc4
|
||||
AA \xc5
|
||||
AE \xc6
|
||||
C, \xc7
|
||||
E! \xc8
|
||||
E' \xc9
|
||||
E> \xca
|
||||
E: \xcb
|
||||
I! \xcc
|
||||
I' \xcd
|
||||
I> \xce
|
||||
I: \xcf
|
||||
D- \xd0
|
||||
N? \xd1
|
||||
O! \xd2
|
||||
O' \xd3
|
||||
O> \xd4
|
||||
O? \xd5
|
||||
O: \xd6
|
||||
*X \xd7
|
||||
O/ \xd8
|
||||
U! \xd9
|
||||
U' \xda
|
||||
U> \xdb
|
||||
U: \xdc
|
||||
Y' \xdd
|
||||
TH \xde
|
||||
ss \xdf
|
||||
a! \xe0
|
||||
a' \xe1
|
||||
a> \xe2
|
||||
a? \xe3
|
||||
a: \xe4
|
||||
aa \xe5
|
||||
ae \xe6
|
||||
c, \xe7
|
||||
e! \xe8
|
||||
e' \xe9
|
||||
e> \xea
|
||||
e: \xeb
|
||||
i! \xec
|
||||
i' \xed
|
||||
i> \xee
|
||||
i: \xef
|
||||
d- \xf0
|
||||
n? \xf1
|
||||
o! \xf2
|
||||
o' \xf3
|
||||
o> \xf4
|
||||
o? \xf5
|
||||
o: \xf6
|
||||
-: \xf7
|
||||
o/ \xf8
|
||||
u! \xf9
|
||||
u' \xfa
|
||||
u> \xfb
|
||||
u: \xfc
|
||||
y' \xfd
|
||||
th \xfe
|
||||
y: \xff
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* This file contains changes from the Open Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Copyright 1988, 1989 by the Massachusetts Institute of Technology
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose and without fee is
|
||||
hereby granted, provided that the above copyright notice
|
||||
appear in all copies and that both that copyright notice and
|
||||
this permission notice appear in supporting documentation,
|
||||
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
|
||||
used in advertising or publicity pertaining to distribution
|
||||
of the software without specific, written prior permission.
|
||||
M.I.T. and the M.I.T. S.I.P.B. make no representations about
|
||||
the suitability of this software for any purpose. It is
|
||||
provided "as is" without express or implied warranty.
|
||||
|
||||
$Id$
|
||||
|
||||
*/
|
||||
|
||||
#define _PATH_CONF "/etc/newsyslog.conf"
|
||||
#define _PATH_SYSLOGPID _PATH_VARRUN "syslog.pid"
|
||||
#define _PATH_GZIP "/usr/bin/gzip"
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 1999 Internet Business Solutions Ltd., Switzerland
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: radius.h,v 1.1 1999/01/28 01:56:34 brian Exp $
|
||||
*/
|
||||
|
||||
struct radius {
|
||||
struct descriptor desc; /* We're a sort of (selectable) descriptor */
|
||||
struct {
|
||||
int fd; /* We're selecting on this */
|
||||
struct rad_handle *rad; /* Using this to talk to our lib */
|
||||
struct pppTimer timer; /* for this long */
|
||||
struct authinfo *auth; /* Tell this about success/failure */
|
||||
} cx;
|
||||
unsigned valid : 1; /* Is this structure valid ? */
|
||||
unsigned vj : 1; /* FRAMED Compression */
|
||||
struct in_addr ip; /* FRAMED IP */
|
||||
struct in_addr mask; /* FRAMED Netmask */
|
||||
unsigned long mtu; /* FRAMED MTU */
|
||||
struct sticky_route *routes; /* FRAMED Routes */
|
||||
struct {
|
||||
char file[MAXPATHLEN]; /* Radius config file */
|
||||
} cfg;
|
||||
};
|
||||
|
||||
#define descriptor2radius(d) \
|
||||
((d)->type == RADIUS_DESCRIPTOR ? (struct radius *)(d) : NULL)
|
||||
|
||||
struct bundle;
|
||||
|
||||
extern void radius_Init(struct radius *);
|
||||
extern void radius_Destroy(struct radius *);
|
||||
|
||||
extern void radius_Show(struct radius *, struct prompt *);
|
||||
extern void radius_Authenticate(struct radius *, struct authinfo *,
|
||||
const char *, const char *, const char *);
|
||||
Reference in new issue
Block a user