This commit was generated by cvs2svn to compensate for changes in r48146,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
David E. O'Brien 1999-06-23 23:40:02 +00:00
commit 0adedf04be
11 changed files with 698 additions and 133 deletions

View File

@ -1,7 +1,38 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 2, Beta 1, Patchlevel 27
April 23, 1999
Version 2
June 22, 1999
README FILE
You should read this file carefully before trying to install or use
the ISC DHCP Distribution.
TABLE OF CONTENTS
1 WHERE TO FIND DOCUMENTATION
2 RELEASE STATUS
3 BUILDING THE DHCP DISTRIBUTION
4 INSTALLING THE DHCP DISTRIBUTION
5 USING THE DHCP DISTRIBUTION
5.1 LINUX
5.1.1 SO_ATTACH_FILTER UNDECLARED
5.1.2 PROTOCOL NOT CONFIGURED
5.1.3 BROADCAST
5.1.4 FIREWALL RULES
5.1.5 IP BOOTP AGENT
5.1.6 MULTIPLE INTERFACES
5.2 SCO
5.3 HP-UX
5.4 ULTRIX
5.5 FreeBSD
5.6 NeXTSTEP
5.7 SOLARIS
6 SUPPORT
6.1 HOW TO REPORT BUGS
7 KNOWN BUGS
WHERE TO FIND DOCUMENTATION
Documentation for this software includes this README file, the
RELNOTES file, and the manual pages, which are in the server, common,
@ -15,25 +46,37 @@ DHCP server documentation is in the dhcpd man page. Information about
the DHCP server lease database is in the dhcpd.leases man page.
Server configuration documentation is in the dhcpd.conf man page as
well as the dhcp-options man page. A sample DHCP server
configuration is in the file server/dhcpd.conf.
configuration is in the file server/dhcpd.conf. The source for the
dhcpd, dhcpd.leases and dhcpd.conf man pages is in the server/ sub-
directory in the distribution. The source for the dhcp-options.5
man page is in the common/ subdirectory.
DHCP Client documentation is in the dhclient man page. DHCP client
configuration documentation is in the dhclient.conf man page and the
dhcp-options man page. The DHCP client configuration script is
documented in the dhclient-script man page. The format of the DHCP
client lease database is documented in the dhclient.leases man page.
The source for all these man pages is in the client/ subdirectory in
the distribution. In addition, the dhcp-options man page should be
referred to for information about DHCP options.
DHCP relay agent documentation is in the dhcrelay man page.
DHCP relay agent documentation is in the dhcrelay man page, the source
for which is distributed in the relay/ subdirectory.
To read installed manual pages, use the man command. Type "man page"
where page is the name of the manual page.
where page is the name of the manual page. This will only work if
you have installed the ISC DHCP distribution using the ``make install''
command (described later).
If you want to read manual pages that aren't installed, you can type
``nroff -man page |more'' where page is the filename of the
unformatted manual page. The filename of an unformatted manual page
is the name of the manual page, followed by '.', followed by some
number - 5 for documentation about files, and 8 for documentation
about programs.
about programs. For example, to read the dhcp-options man page,
you would type ``nroff -man common/dhcp-options.5 |more'', assuming
your current working directory is the top level directory of the ISC
DHCP Distribution.
If you do not have the nroff command, you can type ``more catpage''
where catpage is the filename of the catted man page. Catted man
@ -44,21 +87,20 @@ Please note that until you install the manual pages, the pathnames of
files to which they refer will not be correct for your operating
system.
This is the first Beta release of Version 2 of the Internet Software
RELEASE STATUS
This is the final 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.
This release is stable.
In this release, the server and relay agent currently work well on
NetBSD, Linux after kernel version 2.0.30, FreeBSD, BSD/OS, Ultrix,
Digital Alpha OSF/1, Solaris and SunOS 4.1.4. They run on AIX, HPUX,
IRIX and Linux 2.0.30 and earlier kernels but support only a single
broadcast network interface. 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.
Digital Alpha OSF/1, Solaris and SunOS 4.1.4. On AIX, HPUX, IRIX and
Linux 2.0.30, only a single broadcast network interface is supported.
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.
The DHCP client currently only knows how to configure the network on
NetBSD, FreeBSD, BSD/os, Linux, Solaris and NextStep. The client
@ -86,12 +128,12 @@ information. On Digital Unix, type ``man pfilt''.
To build the DHCP Distribution, unpack the compressed tar file using
the tar utility and the gzip command - type something like:
zcat dhcp-2.0b1pl27.tar.gz |tar xvf -
zcat dhcp-2.0b1pl29.tar.gz |tar xvf -
On BSD/OS, you have to type gzcat, not zcat, and you may run into
similar problems on other operating systems.
Now, cd to the dhcp-2.0b1pl27 subdirectory that you've just created and
Now, cd to the dhcp-2.0b1pl29 subdirectory that you've just created and
configure the source tree by typing:
./configure
@ -112,11 +154,15 @@ 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.
INSTALLING THE DHCP DISTRIBUTION
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''.
USING THE DHCP DISTRIBUTION
LINUX
There are three big LINUX issues: the all-ones broadcast address,
@ -196,6 +242,21 @@ Another route that has worked for some users is:
If you are not using eth0 as your network interface, you should
specify the network interface you *are* using in your route command.
LINUX: FIREWALL RULES
If you are running the DHCP server or client on a Linux system that's
also acting as a firewall, you must be sure to allow DHCP packets
through the firewall - Linux firewalls make filtering decisions before
they make the forwarding decision, so they will filter packets that
are intended for the firewall itself, as well as packets intended to
be forwarded. In particular, your firewall rules _must_ allow
packets from IP address 0.0.0.0 to IP address 255.255.255.255 from UDP
port 68 to UDP port 67 through. They must also allow packets from
your local firewall's IP address and UDP port 67 through to any
address your DHCP server might serve on UDP port 68. Finally,
packets from relay agents on port 67 to the DHCP server on port 67,
and vice versa, must be permitted.
LINUX: IP BOOTP AGENT
Some versions of the Linux 2.1 kernel apparently prevent dhcpd from
@ -206,12 +267,12 @@ working unless you enable it by doing the following:
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
Very old 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.
@ -221,6 +282,10 @@ 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.
Linux 2.1 and later kernels do not use SO_BINDTODEVICE or require the
broadcast address hack, but do support multiple interfaces, using the
Linux Packet Filter.
SCO
SCO has the same problem as Linux (described earlier). The thing is,
@ -335,6 +400,8 @@ before you can report bugs.
PLEASE READ THIS README FILE CAREFULLY BEFORE REPORTING BUGS!
HOW TO REPORT BUGS
When you report bugs, please provide us complete information. A list
of information we need follows. Please read it carefully, and put
all the information you can into your initial bug report, so that we
@ -409,14 +476,9 @@ 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
KNOWN 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.
These two omissions are fixed in the 3.0 release.
DHCPINFORM. The Vendor Specific Data option is not supported. Site-
specific options are not supported. All of these are supported in the
3.0 release of the DHCP distribution, which is now in beta testing.

View File

@ -1,57 +1,72 @@
Internet Software Consortium
Dynamic Host Configuration Protocol Distribution
Version 2, Beta 1, Patchlevel 27
April 23, 1999
Version 2
June 22, 1999
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.
Version 2 of the ISC DHCP Distribution includes the ISC DHCP server,
DHCP Client and DHCP/BOOTP Relay Agent.
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.
was in Beta test from that time to June of 1999, and has now been
released in its final form. It has a number of important features,
and is the release that we would expect most sites to run.
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.
For information on how to install, configure and run this software,
as well as how to find documentation and report bugs, please consult
the README file.
CHANGELOG
This log describes the changes that have been made in version 2.0
since June of 1997.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 29
- Define BYTE_ORDER in includes/cf/hpux.h so that ip.h will compile
correctly on HP-UX.
- Fix a long-standing but minor bug in the way the program name for
syslog was derived.
- Fix a long-standing bug that prevented the DHCP server from broadcasting
responses to BOOTP clients that requested a broadcast response.
- In dhcprequest(), check to make sure that there's a lease before trying
to acknowledge it to the client. This fixes a potential core dump that
a few people observed.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 28
- Fix some pastos I introduced when merging Andrew Chittenden's token
ring support.
- Apply a patch to the token ring support from Andrew Chittenden.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 27
- Add dependencies to makefiles.
- Don't use ping -w 1 in freebsd client script.
- Token ring support for LPF, contributed by Andrew Chittenden.
- Fix a subtle bug that would cause the server to respond incorrectly
in some cases when the client sent duplicate DHCPREQUEST packets.
- Fix option pretty printing for 'X' format.
- Add some special cases to deal with DHCPREQUEST packets from RFC1541
clients.
- Fix an obscure bug in nested subnet mask handling.
- Fix a bug in abandoned lease reclamation.
- Allow maximum message size to be set in configuration file.
- Allow parameter request list to be supplied in configuration file.
CHANGES FROM VERSION 2.0 BETA 1 PATCHLEVEL 26

View File

@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: bpf.c,v 1.19.2.9 1999/03/29 22:07:12 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: bpf.c,v 1.19.2.10 1999/05/27 17:44:51 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -186,6 +186,20 @@ struct bpf_insn dhcp_bpf_filter [] = {
};
int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
struct bpf_insn dhcp_bpf_tr_filter [] = {
/* accept all token ring packets due to variable length header */
/* if we want to get clever, insert the program here */
/* 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_tr_filter_len = (sizeof dhcp_bpf_tr_filter /
sizeof (struct bpf_insn));
#endif
#if defined (USE_BPF_RECEIVE)

View File

@ -0,0 +1,110 @@
/* packet.c
Packet assembly code, originally contributed by Archie Cobbs. */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef lint
static char copyright[] =
"$Id: ethernet.c,v 1.1.2.1 1999/05/27 17:35:47 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/if_ether.h"
#endif /* PACKET_ASSEMBLY || PACKET_DECODING */
#if defined (PACKET_ASSEMBLY)
/* Assemble an hardware header... */
/* XXX currently only supports ethernet; doesn't check for other types. */
void assemble_ethernet_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;
}
#endif /* PACKET_ASSEMBLY */
#ifdef PACKET_DECODING
/* Decode a hardware header... */
ssize_t decode_ethernet_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;
}
#endif /* PACKET_DECODING */

View File

@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
"$Id: lpf.c,v 1.1.2.8 1999/03/29 22:07:13 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
"$Id: lpf.c,v 1.1.2.9 1999/05/27 17:44:52 mellon Exp $ Copyright (c) 1995, 1996, 1998, 1999 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -59,6 +59,9 @@ static char copyright[] =
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
static void lpf_gen_filter_setup PROTO ((struct interface_info *));
static void lpf_tr_filter_setup PROTO ((struct interface_info *));
/* Reinitializes the specified interface after an address change. This
is not required for packet-filter APIs. */
@ -149,15 +152,36 @@ void if_register_send (info)
in bpf includes... */
extern struct sock_filter dhcp_bpf_filter [];
extern int dhcp_bpf_filter_len;
extern struct sock_filter dhcp_bpf_tr_filter [];
extern int dhcp_bpf_tr_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);
if (info -> hw_address.htype == HTYPE_IEEE802)
lpf_tr_filter_setup (info);
else
lpf_gen_filter_setup (info);
if (!quiet_interface_discovery)
note ("Listening on LPF/%s/%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 ?
info -> shared_network -> name : ""));
}
static void lpf_gen_filter_setup (info)
struct interface_info *info;
{
struct sock_fprog p;
/* Set up the bpf filter program structure. This is defined in
bpf.c */
p.len = dhcp_bpf_filter_len;
@ -178,15 +202,35 @@ void if_register_receive (info)
"in your kernel configuration");
error ("Can't install packet filter program: %m");
}
if (!quiet_interface_discovery)
note ("Listening on LPF/%s/%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 ?
info -> shared_network -> name : ""));
}
static void lpf_tr_filter_setup (info)
struct interface_info *info;
{
struct sock_fprog p;
/* Set up the bpf filter program structure. This is defined in
bpf.c */
p.len = dhcp_bpf_tr_filter_len;
p.filter = dhcp_bpf_tr_filter;
/* Patch the server port into the LPF program...
XXX changes to filter program may require changes
XXX to the insn number(s) used below!
XXX Token ring filter is null - when/if we have a filter
XXX that's not, we'll need this code.
XXX dhcp_bpf_filter [?].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");
}
}
#endif /* USE_LPF_RECEIVE */

View File

@ -42,7 +42,7 @@
#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";
"$Id: memory.c,v 1.35.2.4 1999/05/27 17:47:43 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -527,7 +527,6 @@ int supersede_lease (comp, lease, commit)
/* 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,

View File

@ -42,11 +42,12 @@
#ifndef lint
static char copyright[] =
"$Id: options.c,v 1.26.2.7 1999/03/30 02:57:47 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998 The Internet Software Consortium. All rights reserved.\n";
"$Id: options.c,v 1.26.2.10 1999/05/06 21:54:34 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"
#include <ctype.h>
/* Parse all available options out of the specified packet. */
@ -439,7 +440,7 @@ char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
int numhunk = -1;
int numelem = 0;
char fmtbuf [32];
int i, j;
int i, j, k;
char *op = optbuf;
unsigned char *dp = data;
struct in_addr foo;
@ -471,11 +472,21 @@ char *pretty_print_option (code, data, len, emit_commas, emit_quotes)
numhunk = 0;
break;
case 'X':
fmtbuf [i] = 'x';
for (k = 0; k < len; k++) {
if (!isascii (data [k]) ||
!isprint (data [k]))
break;
}
if (k == len) {
fmtbuf [i] = 't';
numhunk = -2;
} else {
fmtbuf [i] = 'x';
hunksize++;
comma = ':';
numhunk = 0;
}
fmtbuf [i + 1] = 0;
hunksize++;
numhunk = 0;
comma = ':';
break;
case 't':
fmtbuf [i] = 't';

View File

@ -3,7 +3,7 @@
Packet assembly code, originally contributed by Archie Cobbs. */
/*
* Copyright (c) 1995, 1996 The Internet Software Consortium.
* Copyright (c) 1995, 1996, 1999 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
"$Id: packet.c,v 1.18.2.4 1999/04/24 15:31:47 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
"$Id: packet.c,v 1.18.2.6 1999/06/10 00:58:16 mellon Exp $ Copyright (c) 1996 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@ -50,7 +50,6 @@ static char copyright[] =
#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. */
@ -122,26 +121,13 @@ void assemble_hw_header (interface, buf, bufix, to)
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);
#if defined (HAVE_TR_SUPPORT)
if (interface -> hw_address.htype == HTYPE_IEEE802)
assemble_tr_header (interface, buf, bufix, to);
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
assemble_ethernet_header (interface, buf, bufix, to);
memcpy (&buf [*bufix], &eh, sizeof eh);
*bufix += sizeof eh;
}
/* UDP header and IP header assembled together for convenience. */
@ -207,7 +193,6 @@ void assemble_udp_ip_header (interface, buf, bufix,
#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;
@ -215,19 +200,12 @@ ssize_t decode_hw_header (interface, buf, bufix, from)
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;
#if defined (HAVE_TR_SUPPORT)
if (interface -> hw_address.htype == HTYPE_IEEE802)
return decode_tr_header (interface, buf, bufix, from);
else
#endif
memcpy (from -> haddr, eh.ether_shost, sizeof (eh.ether_shost));
from -> htype = ARPHRD_ETHER;
from -> hlen = sizeof eh.ether_shost;
return sizeof eh;
return decode_ethernet_header (interface, buf, bufix, from);
}
/* UDP header and IP header decoded together for convenience. */

View File

@ -0,0 +1,307 @@
/*
* packet_tr.c - token ring interface code, contributed in May of 1999
* by Andrew Chittenden
*/
#include "dhcpd.h"
#if defined (HAVE_TR_SUPPORT) && \
(defined (PACKET_ASSEMBLY) || defined (PACKET_DECODING))
#include "includes/netinet/ip.h"
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
#include "netinet/if_tr.h"
#include <sys/time.h>
/*
* token ring device handling subroutines. These are required as token-ring
* does not have a simple on-the-wire header but requires the use of
* source routing
*/
static int insert_source_routing PROTO ((struct trh_hdr *trh, struct interface_info* interface));
static void save_source_routing PROTO ((struct trh_hdr *trh, struct interface_info* interface));
static void expire_routes PROTO ((void));
/*
* As we keep a list of interesting routing information only, a singly
* linked list is all we need
*/
struct routing_entry {
struct routing_entry *next;
unsigned char addr[TR_ALEN];
unsigned char iface[5];
__u16 rcf; /* route control field */
__u16 rseg[8]; /* routing registers */
unsigned long access_time; /* time we last used this entry */
};
static struct routing_entry *routing_info = NULL;
static int routing_timeout = 10;
static struct timeval routing_timer;
void assemble_tr_header (interface, buf, bufix, to)
struct interface_info *interface;
unsigned char *buf;
int *bufix;
struct hardware *to;
{
struct trh_hdr *trh;
int hdr_len;
struct trllc *llc;
/* set up the token header */
trh = (struct trh_hdr *) &buf[*bufix];
if (interface -> hw_address.hlen == sizeof (trh->saddr))
memcpy (trh->saddr, interface -> hw_address.haddr,
sizeof (trh->saddr));
else
memset (trh->saddr, 0x00, sizeof (trh->saddr));
if (to && to -> hlen == 6) /* XXX */
memcpy (trh->daddr, to -> haddr, sizeof trh->daddr);
else
memset (trh->daddr, 0xff, sizeof (trh->daddr));
hdr_len = insert_source_routing (trh, interface);
trh->ac = AC;
trh->fc = LLC_FRAME;
/* set up the llc header for snap encoding after the tr header */
llc = (struct trllc *)(buf + *bufix + hdr_len);
llc->dsap = EXTENDED_SAP;
llc->ssap = EXTENDED_SAP;
llc->llc = UI_CMD;
llc->protid[0] = 0;
llc->protid[1] = 0;
llc->protid[2] = 0;
llc->ethertype = htons(ETHERTYPE_IP);
hdr_len += sizeof(struct trllc);
*bufix += hdr_len;
}
static unsigned char tr_broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
/*
* decoding the token header is a bit complex as you can see here. It is
* further complicated by the linux kernel stripping off some valuable
* information (see comment below) even though we've asked for the raw
* packets.
*/
ssize_t decode_tr_header (interface, buf, bufix, from)
struct interface_info *interface;
unsigned char *buf;
int bufix;
struct hardware *from;
{
struct trh_hdr *trh = (struct trh_hdr *) buf + bufix;
struct trllc *llc;
struct ip *ip;
struct udphdr *udp;
unsigned int route_len = 0;
ssize_t hdr_len;
struct timeval now;
/* see whether any source routing information has expired */
gettimeofday(&now, NULL);
if (routing_timer.tv_sec == 0)
routing_timer.tv_sec = now.tv_sec + routing_timeout;
else if ((now.tv_sec - routing_timer.tv_sec) > 0)
expire_routes();
/* the kernel might have stripped off the source
* routing bit. We try a heuristic to determine whether
* this is the case and put it back on if so
*/
route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
llc = (struct trllc *)(buf + bufix + sizeof(struct trh_hdr)-TR_MAXRIFLEN+route_len);
if (llc->dsap == EXTENDED_SAP
&& llc->ssap == EXTENDED_SAP
&& llc->llc == UI_CMD
&& llc->protid[0] == 0
&& llc->protid[1] == 0
&& llc->protid[2] == 0) {
/* say there is source routing information present */
trh->saddr[0] |= TR_RII;
}
if (trh->saddr[0] & TR_RII)
route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
else
route_len = 0;
hdr_len = sizeof (struct trh_hdr) - TR_MAXRIFLEN + route_len;
/* now filter out unwanted packets: this is based on the packet
* filter code in bpf.c */
llc = (struct trllc *)(buf + bufix + hdr_len);
ip = (struct ip *) (llc + 1);
udp = (struct udphdr *) ((unsigned char*) ip + ip->ip_hl * 4);
/* make sure it is a snap encoded, IP, UDP, unfragmented packet sent
* to our port */
if (llc->dsap != EXTENDED_SAP
|| ntohs(llc->ethertype) != ETHERTYPE_IP
|| ip->ip_p != IPPROTO_UDP
|| (ip->ip_off & IP_OFFMASK) != 0
|| udp->uh_dport != local_port)
return -1;
/* only save source routing information for packets from valued hosts */
save_source_routing(trh, interface);
return hdr_len + sizeof (struct trllc);
}
/* insert_source_routing inserts source route information into the token ring
* header
*/
static int insert_source_routing (trh, interface)
struct trh_hdr *trh;
struct interface_info* interface;
{
struct routing_entry *rover;
struct timeval now;
unsigned int route_len = 0;
gettimeofday(&now, NULL);
/* single route broadcasts as per rfc 1042 */
if (memcmp(trh->daddr, tr_broadcast,TR_ALEN) == 0) {
trh->saddr[0] |= TR_RII;
trh->rcf = ((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
trh->rcf = htons(trh->rcf);
} else {
/* look for a routing entry */
for (rover = routing_info; rover != NULL; rover = rover->next) {
if (memcmp(rover->addr, trh->daddr, TR_ALEN) == 0)
break;
}
if (rover != NULL) {
/* success: route that frame */
if ((rover->rcf & TR_RCF_LEN_MASK) >> 8) {
__u16 rcf = rover->rcf;
memcpy(trh->rseg,rover->rseg,sizeof(trh->rseg));
rcf ^= TR_RCF_DIR_BIT;
rcf &= ~TR_RCF_BROADCAST_MASK;
trh->rcf = htons(rcf);
trh->saddr[0] |= TR_RII;
}
rover->access_time = now.tv_sec;
} else {
/* we don't have any routing information so send a
* limited broadcast */
trh->saddr[0] |= TR_RII;
trh->rcf = ((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK;
trh->rcf |= (TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST);
trh->rcf = htons(trh->rcf);
}
}
/* return how much of the header we've actually used */
if (trh->saddr[0] & TR_RII)
route_len = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
else
route_len = 0;
return sizeof (struct trh_hdr) - TR_MAXRIFLEN + route_len;
}
/*
* save any source routing information
*/
static void save_source_routing(trh, interface)
struct trh_hdr *trh;
struct interface_info *interface;
{
struct routing_entry *rover;
struct timeval now;
unsigned char saddr[TR_ALEN];
__u16 rcf = 0;
gettimeofday(&now, NULL);
memcpy(saddr, trh->saddr, sizeof(saddr));
saddr[0] &= 0x7f; /* strip off source routing present flag */
/* scan our table to see if we've got it */
for (rover = routing_info; rover != NULL; rover = rover->next) {
if (memcmp(&rover->addr[0], &saddr[0], TR_ALEN) == 0)
break;
}
/* found an entry so update it with fresh information */
if (rover != NULL) {
if ((trh->saddr[0] & TR_RII)
&& (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2)) {
rcf = ntohs(trh->rcf);
rcf &= ~TR_RCF_BROADCAST_MASK;
memcpy(rover->rseg, trh->rseg, sizeof(rover->rseg));
}
rover->rcf = rcf;
rover->access_time = now.tv_sec;
return; /* that's all folks */
}
/* no entry found, so create one */
rover = malloc(sizeof(struct routing_entry));
if (rover == NULL) {
fprintf(stderr,
"%s: unable to save source routing information\n",
__FILE__);
return;
}
memcpy(rover->addr, saddr, sizeof(rover->addr));
memcpy(rover->iface, interface->name, 5);
rover->access_time = now.tv_sec;
if (trh->saddr[0] & TR_RII) {
if (((ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8) > 2) {
rcf = ntohs(trh->rcf);
rcf &= ~TR_RCF_BROADCAST_MASK;
memcpy(rover->rseg, trh->rseg, sizeof(rover->rseg));
}
rover->rcf = rcf;
}
/* insert into list */
rover->next = routing_info;
routing_info = rover;
return;
}
/*
* get rid of old routes
*/
static void expire_routes()
{
struct routing_entry *rover;
struct routing_entry **prover = &routing_info;
struct timeval now;
gettimeofday(&now, NULL);
while((rover = *prover) != NULL) {
if ((now.tv_sec - rover->access_time) > routing_timeout) {
*prover = rover->next;
free(rover);
} else
prover = &rover->next;
}
/* Reset the timer */
routing_timer.tv_sec = now.tv_sec + routing_timeout;
routing_timer.tv_usec = now.tv_usec;
}
#endif

View File

@ -106,6 +106,8 @@ struct packet {
of local sender (maybe gateway). */
struct shared_network *shared_network;
struct option_data options [256];
int got_requested_address; /* True if client sent the
dhcp-requested-address option. */
};
struct hardware {
@ -163,6 +165,12 @@ struct lease_state {
int max_message_size;
u_int8_t *prl;
int prl_len;
int got_requested_address; /* True if client sent the
dhcp-requested-address option. */
int got_server_identifier; /* True if client sent the
dhcp-server-identifier option. */
struct shared_network *shared_network; /* Shared network of interface
on which request arrived. */
u_int32_t xid;
u_int16_t secs;
@ -921,6 +929,20 @@ ssize_t decode_udp_ip_header PROTO ((struct interface_info *, unsigned char *,
int, struct sockaddr_in *,
unsigned char *, int));
/* ethernet.c */
void assemble_ethernet_header PROTO ((struct interface_info *, unsigned char *,
int *, struct hardware *));
ssize_t decode_ethernet_header PROTO ((struct interface_info *,
unsigned char *,
int, struct hardware *));
/* tr.c */
void assemble_tr_header PROTO ((struct interface_info *, unsigned char *,
int *, struct hardware *));
ssize_t decode_tr_header PROTO ((struct interface_info *,
unsigned char *,
int, struct hardware *));
/* dhxpxlt.c */
void convert_statement PROTO ((FILE *));
void convert_host_statement PROTO ((FILE *, jrefproto));

View File

@ -0,0 +1,3 @@
/* Current version of ISC DHCP Distribution. */
#define DHCP_VERSION "2.0"