2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-29 13:28:14 +00:00

DHCP Server Daemon

This commit is contained in:
Ted Lemon 1995-11-29 07:40:04 +00:00
commit d7837182d3
64 changed files with 18448 additions and 0 deletions

78
Design Normal file
View File

@ -0,0 +1,78 @@
Objects that need to be tracked:
Node Names
- A node name is the name of a node attached to a network.
- Nodes can be any type of hardware that is attached to a
network and requires one or more addresses.
- Node names may be associated with a specific hardware
address or set of hardware addresses.
- Node names may also be associated with a specific IP address
or set of IP addresses.
Interfaces
- An interface is known by its hardware address, which must be
unique. This works for Ethernet, but may be complicated by
PPP (?). What about IBM token ring and FDDI?
- An interface may be associated with a specific node name,
a specific address, or both.
IP Addresses
- An interface may be associated with a single IP address.
4.4BSD supports IP aliasing so that a single interface can
have multiple addresses, but this probably isn't worth
supporting explicitly.
Transitions
- A machine may be moved to a different net
- If the machine's personality hasn't changed, we may want
to assign it a new IP address but keep the same node name.
- If the machine's personality *has* changed, we need to
assign it both a new node name and a new IP address.
- A machine's hardware may be upgraded.
- The new machine should get the old IP Address and Node Name.
- The old machine may need a new IP address and Node Name.
Static Configuration File
- Addresses which server may assign to arbitrary hosts
- Addresses which are statically assigned to particular
hardware, but which server may need to provide
- Allowable lease length for a given address
Dynamic Server Database
- Addresses which have been dynamically assigned
- The hardware addresses to which they have been assigned
- The lease expiry time on each assigned address
Sample static configuration file:
# One 12-bit subnet, may assign addresses 240 through 4190.
network 16.3.16.0 netmask 255.255.240.0
address-range 240 through 4190;
# One 4-bit subnet, may assign addresses 2 through 6.
network 192.5.5.16 netmask 255.255.255.240
address-range 192.5.5.2 through 192.5.5.6;
# 16 12-bit subnets, may assign addresses 128 through 4190 of each network.
# Address ranges are shared with listed servers [TBI].
networks 16.1.0.0 through 16.1.240.0 netmask 255.255.240.0
address-range 0.128 through 31.240
shared-with dhcp-1.pa.dec.com, dhcp-2.pa.dec.com, dhcp-3.pa.dec.com;
Sample database file:
# January 12, 1996, 16:42:37
timestamp 1049897235;
lease 204.254.239.7 starts 1049897235 ends 1049957235
hardware ethernet 08:00:2b:4c:29:35
uid 08:00:2b:4c:29:35 host minuet class decstations;
lease 204.254.239.8 starts 1049897235 ends 1049957235
hardware ethernet 08:00:2b:22:09:27
uid 08:00:2b:22:09:27 class decstations;
lease 204.254.239.9 starts 1049897235 ends 1049957235
hardware ethernet 08:00:42:29:09:42
uid 08:00:42:29:09:42;
lease 204.254.239.240 starts 1049897235 ends 1049957235
uid 50:50:50:3a:6b:69:6d:62:61 host kimba-ppp;

8
Makefile Normal file
View File

@ -0,0 +1,8 @@
SRCS = dhcpd.c options.c errwarn.c convert.c conflex.c confpars.c \
tree.c memory.c bootp.c dhcp.c alloc.c print.c socket.c \
hash.c tables.c
PROG = dhcpd
.include <bsd.prog.mk>
CFLAGS += -DDEBUG -g

197
alloc.c Normal file
View File

@ -0,0 +1,197 @@
/* alloc.c
Memory allocation...
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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.\n");
return foo;
}
void dfree (ptr, name)
VOIDPTR ptr;
char *name;
{
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 *new_tree_cache (name)
char *name;
{
struct tree_cache *rval = dmalloc (sizeof (struct tree_cache), 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;
}
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;
{
dfree ((VOIDPTR)ptr, name);
}
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);
}

147
bootp.c Normal file
View File

@ -0,0 +1,147 @@
/* bootp.c
BOOTP Protocol support. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
void bootp (packet)
struct packet *packet;
{
int result;
struct host_decl *hp = find_host_by_addr (packet -> raw -> htype,
packet -> raw -> chaddr,
packet -> raw -> hlen);
struct dhcp_packet *reply;
struct sockaddr_in to;
/* If the packet is from a host we don't know, drop it on
the floor. XXX */
if (!hp) {
note ("Can't find record for BOOTP host %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
return;
}
/* If we don't have a fixed address for it, drop it on the floor.
XXX */
if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr)) {
note ("No fixed address for BOOTP host %s (%s)",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr),
hp -> name);
return;
}
reply = new_dhcp_packet ("bootp");
if (!reply) {
free_dhcp_packet (packet -> raw, "bootp");
free_packet (packet, "bootp");
return;
}
/* Take the fields that we care about... */
reply -> op = BOOTREPLY;
reply -> htype = packet -> raw -> htype;
reply -> hlen = packet -> raw -> hlen;
memcpy (reply -> chaddr, packet -> raw -> chaddr, reply -> hlen);
memset (&reply -> chaddr [reply -> hlen], 0,
(sizeof reply -> chaddr) - reply -> hlen);
reply -> hops = packet -> raw -> hops;
reply -> xid = packet -> raw -> xid;
reply -> secs = packet -> raw -> secs;
reply -> flags = 0;
reply -> ciaddr = packet -> raw -> ciaddr;
if (!tree_evaluate (hp -> fixed_addr))
warn ("tree_evaluate failed.");
debug ("fixed_addr: %x %d %d %d %d %x",
*(int *)(hp -> fixed_addr -> value), hp -> fixed_addr -> len,
hp -> fixed_addr -> buf_size, hp -> fixed_addr -> timeout,
hp -> fixed_addr -> tree);
memcpy (&reply -> yiaddr, hp -> fixed_addr -> value,
sizeof reply -> yiaddr);
reply -> siaddr.s_addr = pick_interface (packet);
reply -> giaddr = packet -> raw -> giaddr;
if (hp -> server_name) {
strncpy (reply -> sname, hp -> server_name,
(sizeof reply -> sname) - 1);
reply -> sname [(sizeof reply -> sname) - 1] = 0;
}
if (hp -> filename) {
strncpy (reply -> file, hp -> filename,
(sizeof reply -> file) - 1);
reply -> file [(sizeof reply -> file) - 1] = 0;
}
reply -> options [0] = 0;
/* XXX gateways? */
to.sin_port = server_port;
#if 0
if (packet -> raw -> flags & BOOTP_BROADCAST)
#endif
to.sin_addr.s_addr = INADDR_BROADCAST;
#if 0
else
to.sin_addr.s_addr = INADDR_ANY;
#endif
memset (reply -> options, 0, sizeof (reply -> options));
/* If we got the magic cookie, send it back. */
if (packet -> options_valid)
memcpy (reply -> options, packet -> raw -> options, 4);
to.sin_port = packet -> client.sin_port;
to.sin_family = AF_INET;
to.sin_len = sizeof to;
memset (to.sin_zero, 0, sizeof to.sin_zero);
note ("Sending bootp reply to %s, port %d",
inet_ntoa (to.sin_addr), htons (to.sin_port));
errno = 0;
result = sendto (packet -> client_sock, reply,
((char *)(&reply -> options) - (char *)reply) + 64,
0, (struct sockaddr *)&to, sizeof to);
if (result < 0)
warn ("sendto: %m");
}

49
cdefs.h Normal file
View File

@ -0,0 +1,49 @@
/* cdefs.h
Standard C definitions... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#if defined (__GNUC__) || defined (__STDC__)
#define PROTO(x) x
#define KandR(x)
#define ANSI_DECL(x) x
#define INLINE inline
#else
#define PROTO(x) ()
#define KandR(x) x
#define ANSI_DECL(x)
#define INLINE
#endif

106
cf/bsdos.h Normal file
View File

@ -0,0 +1,106 @@
/* bsdos.h
System dependencies for BSD/os... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#include <sys/types.h>
#include <string.h>
#include <paths.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <setjmp.h>
#include <limits.h>
#include <netdb.h>
extern int h_errno;
#include <net/if.h>
/* Time stuff... */
#include <sys/time.h>
#define TIME struct timeval
#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
#define TIME_DIFF_US(high, low) \
(((high) -> tv_sec - (low) -> tv_sec) * 1000000 \
+ ((high) -> tv_usec - (low) -> tv_usec))
#define SET_TIME(x, y) (((x) -> tv_sec = ((y) / 1000000)), \
((x) -> tv_usec = ((y) % 1000000)))
#define DELAY() usleep (2000)
#define DELAY_ONE_SECOND() usleep (1000000)
/* Login stuff... */
#include <utmp.h>
#include <sys/syslimits.h>
#define _PATH_LOGIN "/usr/bin/login"
#define SETLOGIN(x) setlogin (x)
#define SETUID(x) setuid (x)
#define SETGID(x) (setgroups (0, &x), setgid (x))
#define USER_MAX UT_NAMESIZE
/* Varargs stuff... */
#include <stdarg.h>
#define VA_DOTDOTDOT ...
#define va_dcl
#define VA_start(list, last) va_start (list, last)
#define _PATH_MPOOL_PID "/var/run/mpoold.pid"
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#include <sys/time.h>
#define TIME struct timeval
#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
#define TIME_DIFF(high, low) \
(((high) -> tv_sec == (low) -> tv_sec) \
? ((high) -> tv_usec > (low) -> tv_usec \
? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
: (high) -> tv_sec - (low) -> tv_sec)
#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
#define ADD_TIME(d, s1, s2) { \
(d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
(d) -> tv_sec = (d) -> tv_usec / 1000000; \
(d) -> tv_usec %= 1000000; \
} else \
(d) -> tv_sec = 0; \
(d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
}
#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
((x) -> tv_usec = 999999))

73
cf/netbsd.h Normal file
View File

@ -0,0 +1,73 @@
/* netbsd.h
System dependencies for NetBSD... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#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>
#include <netdb.h>
extern int h_errno;
#include <net/if.h>
/* Varargs stuff... */
#include <stdarg.h>
#define VA_DOTDOTDOT ...
#define va_dcl
#define VA_start(list, last) va_start (list, last)
#define _PATH_DHCPD_PID "/var/run/dhcpd.pid"
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#include <sys/time.h>
#define TIME time_t
#define GET_TIME(x) time ((x))
#define TIME_DIFF(high, low) (*(high) - *(low))
#define SET_TIME(x, y) (*(x) = (y))
#define ADD_TIME(d, s1, s2) (*(d) = *(s1) + *(s2))
#define SET_MAX_TIME(x) (*(x) = INT_MAX)

83
cf/sunos4.h Normal file
View File

@ -0,0 +1,83 @@
/* sunos4.h
System dependencies for SunOS 4 (tested on 4.1.4)... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <setjmp.h>
#include <limits.h>
#include <netdb.h>
extern int h_errno;
#include <net/if.h>
/* Varargs stuff... */
#include <varargs.h>
#define VA_DOTDOTDOT va_alist
#define VA_start(list, last) va_start (list)
#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list)
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#include <sys/time.h>
#define TIME struct timeval
#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
#define TIME_DIFF(high, low) \
(((high) -> tv_sec == (low) -> tv_sec) \
? ((high) -> tv_usec > (low) -> tv_usec \
? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
: (high) -> tv_sec - (low) -> tv_sec)
#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
#define ADD_TIME(d, s1, s2) { \
(d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
(d) -> tv_sec = (d) -> tv_usec / 1000000; \
(d) -> tv_usec %= 1000000; \
} else \
(d) -> tv_sec = 0; \
(d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
}
#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
((x) -> tv_usec = 999999))

197
common/alloc.c Normal file
View File

@ -0,0 +1,197 @@
/* alloc.c
Memory allocation...
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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.\n");
return foo;
}
void dfree (ptr, name)
VOIDPTR ptr;
char *name;
{
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 *new_tree_cache (name)
char *name;
{
struct tree_cache *rval = dmalloc (sizeof (struct tree_cache), 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;
}
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;
{
dfree ((VOIDPTR)ptr, name);
}
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);
}

280
common/conflex.c Normal file
View File

@ -0,0 +1,280 @@
/* conflex.c
Lexical scanner for dhcpd config file... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "dhctoken.h"
#include <ctype.h>
static int line;
static int lpos;
int tlpos;
int tline;
static int token;
static int ugflag;
static char *tval;
static char tokbuf [1500];
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_atom PROTO ((int, FILE *));
static int intern PROTO ((char *, int));
static int get_char (cfile)
FILE *cfile;
{
char c = getc (cfile);
if (!ugflag) {
if (c == EOL) {
line++;
lpos = 1;
} else {
lpos++;
}
} else
ugflag = 0;
return c;
}
static int get_token (cfile)
FILE *cfile;
{
int c;
int i;
int ttok;
do {
c = get_char (cfile);
if (isascii (c) && isspace (c))
continue;
if (c == '#') {
skip_to_eol (cfile);
continue;
}
tlpos = lpos;
tline = line;
if (c == '"') {
ttok = read_string (cfile);
break;
}
if (isascii (c) && isdigit (c)) {
ttok = read_number (c, cfile);
break;
} else if (isascii (c) && isalpha (c)) {
ttok = read_num_or_atom (c, cfile);
break;
} else {
tval = 0;
ttok = c;
break;
}
} while (1);
return ttok;
}
int next_token (rval, cfile)
char **rval;
FILE *cfile;
{
int rv;
if (token) {
rv = token;
token = 0;
} else {
rv = get_token (cfile);
}
if (rval)
*rval = tval;
return rv;
}
int peek_token (rval, cfile)
char **rval;
FILE *cfile;
{
if (!token)
token = get_token (cfile);
if (rval)
*rval = tval;
return token;
}
static void skip_to_eol (cfile)
FILE *cfile;
{
int c;
do {
c = get_char (cfile);
if (c == EOF)
return;
if (c == EOL) {
ungetc (c, cfile);
ugflag = 1;
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;
tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (!seenx && c == 'x')
seenx = 1;
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 NUMBER;
}
static int read_num_or_atom (c, cfile)
int c;
FILE *cfile;
{
int i = 0;
int rv = NUMBER_OR_ATOM;
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 = ATOM;
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;
{
switch (atom [0]) {
case 'h':
if (!strcasecmp (atom + 1, "ost"))
return HOST;
if (!strcasecmp (atom + 1, "ardware"))
return HARDWARE;
break;
case 'f':
if (!strcasecmp (atom + 1, "ilename"))
return FILENAME;
if (!strcasecmp (atom + 1, "ixed-address"))
return FIXED_ADDR;
break;
case 'e':
if (!strcasecmp (atom + 1, "thernet"))
return ETHERNET;
break;
case 'o':
if (!strcasecmp (atom + 1, "ption"))
return OPTION;
break;
}
return dfv;
}

117
common/convert.c Normal file
View File

@ -0,0 +1,117 @@
/* 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 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[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
unsigned long getULong (buf)
unsigned char *buf;
{
unsigned long ibuf;
memcpy (&ibuf, buf, sizeof (unsigned long));
return ntohl (ibuf);
}
long getLong (buf)
unsigned char *buf;
{
long ibuf;
memcpy (&ibuf, buf, sizeof (long));
return ntohl (ibuf);
}
unsigned short getUShort (buf)
unsigned char *buf;
{
unsigned short ibuf;
memcpy (&ibuf, buf, sizeof (unsigned short));
return ntohs (ibuf);
}
short getShort (buf)
unsigned char *buf;
{
short ibuf;
memcpy (&ibuf, buf, sizeof (short));
return ntohs (ibuf);
}
void putULong (obuf, val)
unsigned char *obuf;
unsigned long val;
{
unsigned long tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putLong (obuf, val)
unsigned char *obuf;
long val;
{
long tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putUShort (obuf, val)
unsigned char *obuf;
unsigned short val;
{
unsigned short tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putShort (obuf, val)
unsigned char *obuf;
short val;
{
short tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}

200
common/errwarn.c Normal file
View File

@ -0,0 +1,200 @@
/* errwarn.c
Errors and warnings... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 RadioMail Corporation. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <syslog.h>
#include <errno.h>
static void do_percentm PROTO ((char *obuf, char *ibuf));
static char mbuf [1024];
static char fbuf [1024];
/* Log an error message, then exit... */
int 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_ERR, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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_ERR, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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_INFO, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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_DEBUG, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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;
while (*s)
{
if (infmt)
{
if (*s == 'm')
{
strcpy (p - 1, strerror (errno));
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
{
extern int tline, tlpos;
va_list list;
do_percentm (mbuf, fmt);
snprintf (fbuf, sizeof fbuf, "dhcpd.conf line %d char %d: %s",
tline, tlpos, mbuf);
VA_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
syslog (LOG_ERROR, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
return 0;
}

152
common/hash.c Normal file
View File

@ -0,0 +1,152 @@
/* hash.c
Routines for manipulating hash tables... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
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,
DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
return rv;
}
static INLINE do_hash (name, len, size)
char *name;
int len;
int size;
{
register int accum = 0;
register unsigned char *s = (unsigned char *)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;
char *name;
unsigned char *pointer;
{
int hashno = do_hash (name, len, table -> hash_count);
struct hash_bucket *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];
table -> buckets [hashno] = bp;
}
void delete_hash_entry (table, name, len)
struct hash_table *table;
int len;
char *name;
{
int hashno = do_hash (name, len, table -> hash_count);
struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
/* 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 (bp -> name, 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;
}
}
}
unsigned char *hash_lookup (table, name, len)
struct hash_table *table;
char *name;
int len;
{
int hashno = do_hash (name, len, table -> hash_count);
struct hash_bucket *bp;
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 (bp -> name, name))
return bp -> value;
}
return (unsigned char *)0;
}

395
common/memory.c Normal file
View File

@ -0,0 +1,395 @@
/* memory.c
Memory-resident database... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static struct host_decl *hosts;
static struct hash_table *subnet_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;
void enter_host (hd)
struct host_decl *hd;
{
hd -> n_name = hosts;
hd -> n_haddr = hosts;
hd -> n_cid = hosts;
hosts = hd;
}
struct host_decl *find_host_by_name (name)
char *name;
{
struct host_decl *foo;
for (foo = hosts; foo; foo = foo -> n_name)
if (!strcmp (name, foo -> name))
return foo;
return (struct host_decl *)0;
}
struct host_decl *find_host_by_addr (htype, haddr, hlen)
int htype;
unsigned char *haddr;
int hlen;
{
struct host_decl *foo;
int i;
for (foo = hosts; foo; foo = foo -> n_haddr)
for (i = 0; i < foo -> interface_count; i++)
if (foo -> interfaces [i].htype == htype &&
foo -> interfaces [i].hlen == hlen &&
!memcmp (foo -> interfaces [i].haddr, haddr, hlen))
return foo;
return (struct host_decl *)0;
}
void new_address_range (low, high, netmask)
struct in_addr low, high, netmask;
{
struct lease *address_range, *lp, *plp;
struct subnet *subnet;
struct in_addr net;
int i, max;
char lowbuf [16], highbuf [16], netbuf [16];
/* Initialize the hash table if it hasn't been done yet. */
if (!subnet_hash)
subnet_hash = new_hash ();
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.s_addr = SUBNET (low, netmask);
if (net.s_addr != SUBNET (high, netmask)) {
strcpy (lowbuf, inet_ntoa (low));
strcpy (highbuf, inet_ntoa (high));
strcpy (netbuf, inet_ntoa (netmask));
error ("Address range %s to %s, netmask %s spans %s!",
lowbuf, highbuf, netbuf, "multiple subnets");
}
/* See if this subnet is already known - if not, make a new one. */
subnet = find_subnet (net);
if (!subnet) {
subnet = new_subnet ("new_address_range");
if (!subnet)
error ("No memory for new subnet");
subnet -> net = net;
subnet -> netmask = netmask;
subnet -> leases = (struct lease *)0;
enter_subnet (subnet);
}
/* Get the high and low host addresses... */
max = HOST_ADDR (high, netmask);
i = HOST_ADDR (low, netmask);
/* Allow range to be specified high-to-low as well as low-to-high. */
if (i > max) {
max = i;
i = HOST_ADDR (high, netmask);
}
/* Get a lease structure for each address in the range. */
address_range = new_leases (max - i + 1, "new_address_range");
if (!address_range) {
strcpy (lowbuf, inet_ntoa (low));
strcpy (highbuf, inet_ntoa (high));
error ("No memory for address range %s-%s.", lowbuf, highbuf);
}
memset (address_range, 0, (sizeof *address_range) * (max - i + 1));
/* Fill out the lease structures with some minimal information. */
for (; i <= max; i++) {
address_range [i].ip_addr.s_addr = IP_ADDR (subnet -> net, i);
address_range [i].starts =
address_range [i].timestamp = MIN_TIME;
address_range [i].ends = MIN_TIME;
address_range [i].contain = subnet;
/* Link this entry into the list. */
address_range [i].next = subnet -> leases;
address_range [i].prev = (struct lease *)0;
subnet -> leases = &address_range [i];
address_range [i].next -> prev = subnet -> leases;
add_hash (lease_ip_addr_hash,
(char *)&address_range [i].ip_addr,
sizeof address_range [i].ip_addr,
(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 in_addr lnet;
int lhost;
lnet.s_addr = SUBNET (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 (lnet.s_addr == subnet -> net.s_addr &&
lhost >= i && lhost <= max) {
if (plp) {
plp -> next = lp -> next;
} else {
dangling_leases = lp -> next;
}
lp -> next = (struct lease *)0;
supersede_lease (&address_range [lhost - i], lp);
free_lease (lp, "new_address_range");
} else
plp = lp;
}
}
struct subnet *find_subnet (subnet)
struct in_addr subnet;
{
struct subnet *rv;
return (struct subnet *)hash_lookup (subnet_hash,
(char *)&subnet, sizeof subnet);
}
/* Enter a new subnet into the subnet hash. */
void enter_subnet (subnet)
struct subnet *subnet;
{
add_hash (subnet_hash, (char *)&subnet -> net,
sizeof subnet -> net, (unsigned char *)subnet);
}
/* 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",
inet_ntoa (lease -> ip_addr));
}
*comp = *lease;
lease -> next = dangling_leases;
lease -> prev = (struct lease *)0;
dangling_leases = lease;
} else {
supersede_lease (comp, lease);
}
}
/* 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. */
void supersede_lease (comp, lease)
struct lease *comp, *lease;
{
int enter_uid = 0;
int enter_hwaddr = 0;
struct subnet *parent;
struct lease *lp;
/* 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 (comp -> ends > cur_time &&
((comp -> 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",
inet_ntoa (comp -> ip_addr));
} else {
/* If there's a Unique ID, dissociate it from the hash
table if necessary, and always free it. */
if (comp -> uid) {
if (comp -> uid_len != lease -> uid_len ||
memcmp (comp -> uid, lease -> uid,
comp -> uid_len)) {
delete_hash_entry (lease_uid_hash,
comp -> uid,
comp -> uid_len);
enter_uid = 1;
}
free (comp -> uid);
}
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)) {
delete_hash_entry (lease_hw_addr_hash,
comp -> hardware_addr.haddr,
comp -> hardware_addr.hlen);
enter_hwaddr = 1;
}
/* Copy the data files, but not the linkages. */
comp -> starts = lease -> starts;
comp -> ends = lease -> ends;
comp -> timestamp = lease -> timestamp;
comp -> uid = lease -> uid;
comp -> uid_len = lease -> uid_len;
comp -> host = lease -> host;
comp -> hardware_addr = lease -> hardware_addr;
comp -> state = lease -> state;
/* Record the lease in the uid hash if necessary. */
if (enter_uid && lease -> uid) {
add_hash (lease_uid_hash, lease -> uid,
lease -> uid_len, (unsigned char *)lease);
}
/* Record it in the hardware address hash if necessary. */
if (enter_hwaddr && lease -> hardware_addr.htype) {
add_hash (lease_hw_addr_hash,
lease -> hardware_addr.haddr,
lease -> hardware_addr.hlen,
(unsigned char *)lease);
}
/* Remove the lease from its current place in the list. */
if (comp -> prev) {
comp -> prev -> next = comp -> next;
} else {
comp -> contain -> leases = comp -> next;
}
if (comp -> next) {
comp -> next -> prev = comp -> prev;
}
/* Find the last insertion point... */
if (comp == comp -> contain -> insertion_point ||
!comp -> contain -> insertion_point) {
lp = comp -> contain -> leases;
} else {
lp = comp -> contain -> insertion_point;
}
if (!lp) {
/* Nothing on the list yet? Just make comp the
head of the list. */
comp -> contain -> leases = comp;
} else if (lp -> ends <= comp -> ends) {
/* Skip down the list until we run out of list
or find a place for comp. */
while (lp -> next && lp -> ends < comp -> ends) {
lp = lp -> next;
}
if (lp -> ends < comp -> ends) {
/* If we ran out of list, put comp
at the end. */
lp -> next = comp;
comp -> prev = lp;
comp -> next = (struct lease *)0;
} else {
/* If we didn't, put it between lp and
the previous item on the list. */
comp -> prev = lp -> prev;
comp -> prev -> next = comp;
comp -> next = lp;
lp -> prev = comp;
}
} else {
/* Skip ip the list until we run out of list
or find a place for comp. */
while (lp -> prev && lp -> ends > comp -> ends) {
lp = lp -> prev;
}
if (lp -> ends > comp -> ends) {
/* If we ran out of list, put comp
at the beginning. */
lp -> prev = comp;
comp -> next = lp;
comp -> prev = (struct lease *)0;
comp -> contain -> leases = comp;
} else {
/* If we didn't, put it between lp and
the next item on the list. */
comp -> next = lp -> next;
comp -> next -> prev = comp;
comp -> prev = lp;
lp -> next = comp;
}
}
comp -> contain -> insertion_point = comp;
}
}

556
common/options.c Normal file
View File

@ -0,0 +1,556 @@
/* options.c
DHCP options parsing and reassembly. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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_LEN);
/* 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,
packet -> raw -> file,
sizeof packet -> raw -> file);
if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)
parse_option_buffer (packet,
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);
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 up options based on client-supplied desired option list (if any)
and selected server option list. */
void cons_options (inpacket, outpacket, hp, overload)
struct packet *inpacket;
struct dhcp_packet *outpacket;
struct host_decl *hp;
int overload; /* Overload flags that may be set. */
{
option_mask options_have; /* Options we can send. */
option_mask options_want; /* Options client wants. */
option_mask options_done; /* Options we've already encoded. */
option_mask temp; /* Working option mask. */
unsigned char *priority_list;
int priority_len;
unsigned char *buffer = inpacket -> raw -> options;
int buflen, bufix;
int reserved = 3; /* Reserved space for overload. */
unsigned char *overload_ptr = (unsigned char *)0;
int stored_length [256];
int missed = 0;
int missed_code;
int missed_length;
int result;
int i;
/* If there's no place to overload with options, don't save space
for an overload option. */
if (!overload)
reserved = 0;
/* Zero out the stored-lengths array. */
memset (stored_length, 0, sizeof stored_length);
/* If the client has provided a maximum DHCP message size,
use that. Otherwise, we use the default MTU size (576 bytes). */
/* XXX Maybe it would be safe to assume that we can send a packet
to the client that's as big as the one it sent us, even if it
didn't specify a large MTU. */
if (inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data)
buflen = (getUShort (inpacket -> options
[DHO_DHCP_MAX_MESSAGE_SIZE].data)
- DHCP_FIXED_LEN);
else
buflen = 576 - DHCP_FIXED_LEN;
/* If the client has provided a list of options that it wishes
returned, use it to prioritize. */
if (inpacket -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
priority_list =
inpacket -> options
[DHO_DHCP_PARAMETER_REQUEST_LIST].data;
priority_len =
inpacket -> options
[DHO_DHCP_PARAMETER_REQUEST_LIST].len;
} else {
/* Otherwise, prioritize based on the default priority list. */
priority_list = dhcp_option_default_priority_list;
priority_len = sizeof_dhcp_option_default_priority_list;
}
/* Make a bitmask of all the options the client wants. */
OPTION_ZERO (options_want);
for (i = 0; i < priority_len; i++)
OPTION_SET (options_want, priority_list [i]);
/* Make a bitmask of all the options we have available. */
OPTION_ZERO (options_have);
for (i = 0; i < 256; i++)
if (hp -> options [i])
OPTION_SET (options_have, i);
again:
/* Try copying out options that fit easily. */
for (i = 0; i < priority_len; i++) {
/* Code for next option to try to store. */
int code = priority_list [i];
/* 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 (!hp -> options [code])
continue;
/* Don't look at options that have already been stored. */
if (OPTION_ISSET (options_done, code))
continue;
/* Find the value of the option... */
if (!tree_evaluate (hp -> options [code]))
continue;
/* We should now have a constant length for the option. */
length = (hp -> options [code] -> len - stored_length [code]);
/* If there's no space for this option, skip it. */
if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
/* If this is the first missed option, remember it. */
if (++missed == 1) {
missed_code = code;
missed_length = length;
}
continue;
}
/* Otherwise, store the option. */
result = store_option (outpacket, code,
buffer + bufix,
buflen - bufix - reserved,
stored_length);
bufix += result;
/* The following test should always succeed because of
preconditioning above. */
if (stored_length [code] == hp -> options [code] -> len)
OPTION_SET (options_done, code);
else {
warn ("%s: Only stored %d out of %d bytes.",
dhcp_options [code].name,
stored_length [code],
hp -> options [code] -> len);
if (++missed == 1) {
missed_code = code;
missed_length = hp -> options [code] -> len
- stored_length [code];
}
}
}
/* If we didn't miss any options, we're done. */
/* XXX Maybe we want to try to encode options the client didn't
request but that we have available? */
if (!missed)
return;
/* If we did miss one or more options, they must not have fit.
It's possible, though, that there's only one option left to
store, and that it would fit if we weren't reserving space
for the overload option. In that case, we want to avoid
overloading. */
if (reserved && missed == 1
&& (bufix + OPTION_SPACE (missed_length) <= buflen)) {
result = store_option (outpacket, missed_code,
buffer + bufix, buflen - bufix,
stored_length);
bufix += result;
/* This test should always fail -- we'll send bad
data if it doesn't. */
if (stored_length [missed_code]
== hp -> options [missed_code] -> len) {
OPTION_SET (options_done, missed_code);
} else {
warn ("%s (last): Only stored %d out of %d bytes.",
dhcp_options [missed_code].name,
stored_length [missed_code],
hp -> options [missed_code] -> len);
}
return;
}
/* We've crammed in all the options that completely fit in
the current buffer, but maybe we can fit part of the next
option into the current buffer and part into the next. */
if (bufix + OPTION_SPACE (missed_length) + reserved
< buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
result = store_option (outpacket, missed_code,
buffer + bufix,
buflen - bufix - reserved,
stored_length);
bufix += result;
/* This test should never fail. */
if (stored_length [missed_code]
== hp -> options [missed_code] -> len) {
OPTION_SET (options_done, missed_code);
warn ("%s: Unexpected completed store.",
dhcp_options [missed_code].name);
}
}
/* Okay, nothing else is going to fit in the current buffer
except possibly the override option. Store that. */
if (reserved) {
buffer [bufix++] = DHO_DHCP_OPTION_OVERLOAD;
buffer [bufix++] = 1;
overload_ptr = buffer + bufix;
buffer [bufix++] = 0;
/* If there's space, store an End option code. */
if (bufix < buflen)
buffer [bufix++] = DHO_END;
/* If there's still space, pad it. */
while (bufix < buflen)
buffer [bufix++] = DHO_PAD;
}
/* If we've fallen through to here, we still have options to
store, and may be able to overload options into the file
and server name fields of the DHCP packet. */
/* We should have stored an overload option by now if we're
going to need it, so if this test fails, there's a programming
error somewhere above. */
if (overload && !overload_ptr) {
warn ("Need to overload, but didn't store overload option!");
return;
}
/* Can we use the file buffer? */
if (overload & 1) {
buffer = inpacket -> raw -> file;
buflen = sizeof inpacket -> raw -> file;
bufix = 0;
overload &= ~1;
goto again;
}
/* Can we use the sname buffer? */
if (overload & 2) {
buffer = inpacket -> raw -> sname;
buflen = sizeof inpacket -> raw -> sname;
bufix = 0;
overload &= ~2;
goto again;
}
warn ("Insufficient packet space for all options.");
}
/* Copy the option data specified by code from the packet structure's
option array into an option buffer specified by buf and buflen,
updating stored_length[code] to reflect the amount of code's option
data that has been stored so far. Return 1 if all the option data
has been stored. */
int store_option (packet, code, buffer, buflen, stored_length)
struct packet *packet;
unsigned char code;
unsigned char *buffer;
int buflen;
int *stored_length;
{
int length = packet -> options [code].len - stored_length [code];
int bufix = 0;
int rv = 1;
if (length > buflen) {
rv = 0;
length = buflen;
}
/* If the option's length is more than 255, we must store it
in multiple hunks. Store 255-byte hunks first. */
/* XXX Might a client lose its cookies if options aren't
chunked out so that each chunk is aligned to the size
of the data being represented? */
while (length) {
unsigned char incr = length > 255 ? 255 : length;
buffer [bufix] = code;
buffer [bufix + 1] = incr;
memcpy (buffer + bufix + 2, (packet -> options [code].data
+ stored_length [code]), incr);
length -= incr;
stored_length [code] += incr;
bufix += 2 + incr;
}
return rv;
}
/* Format the specified option so that a human can easily read it. */
char *pretty_print_option (code, data, len)
unsigned char code;
unsigned char *data;
int len;
{
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;
/* 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 '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;
printf ("numhunk = %d numelem = %d\n", numhunk, numelem);
/* 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':
strcpy (op, dp);
break;
case 'I':
foo.s_addr = htonl (getULong (dp));
strcpy (op, inet_ntoa (foo));
dp += 4;
break;
case 'l':
sprintf (op, "%ld", getLong (dp));
dp += 4;
break;
case 'L':
sprintf (op, "%ld", 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 'f':
strcpy (op, *dp++ ? "true" : "false");
break;
default:
warn ("Unexpected format code %c", fmtbuf [j]);
}
op += strlen (op);
*op++ = ' ';
}
}
*--op = 0;
return optbuf;
}

65
common/print.c Normal file
View File

@ -0,0 +1,65 @@
/* print.c
Turn data structures into printable text. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
char *print_hw_addr (htype, hlen, data)
int htype;
int hlen;
unsigned char *data;
{
static char habuf [49];
char *s;
int i;
s = habuf;
for (i = 0; i < hlen; i++) {
sprintf (s, "%x", data [i]);
s += strlen (s);
*s++ = ':';
}
*--s = 0;
return habuf;
}

208
common/socket.c Normal file
View File

@ -0,0 +1,208 @@
/* socket.c
BSD socket interface code... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/ioctl.h>
/* List of sockets we're accepting packets on... */
struct socklist {
struct socklist *next;
struct sockaddr_in addr;
int sock;
} *sockets;
/* Return the list of IP addresses associated with each network interface. */
u_int32_t *get_interface_list (count)
int *count;
{
u_int32_t *intbuf = (u_int32_t *)0;
static char buf [8192];
struct ifconf ic;
int i;
int sock;
int ifcount = 0;
int ifix = 0;
/* 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);
close (sock);
if (i < 0)
error ("ioctl: SIOCGIFCONF: %m");
again:
/* Cycle through the list of interfaces looking for IP addresses.
Go through twice; once to count the number if addresses, and a
second time to copy them into an array of addresses. */
for (i = 0; i < ic.ifc_len;) {
struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
if (ifp -> ifr_addr.sa_family == AF_INET) {
struct sockaddr_in *foo =
(struct sockaddr_in *)(&ifp -> ifr_addr);
/* We don't want the loopback interface. */
if (foo -> sin_addr.s_addr == INADDR_LOOPBACK)
continue;
if (intbuf)
intbuf [ifix++] = foo -> sin_addr.s_addr;
else
++ifcount;
}
}
/* If we haven't already filled our array, allocate it and go
again. */
if (!intbuf) {
intbuf = (u_int32_t *)dmalloc ((ifcount + 1)
* sizeof (u_int32_t),
"get_interface_list");
if (!intbuf)
return intbuf;
goto again;
}
*count = ifcount;
return intbuf;
}
void listen_on (port, address)
u_int16_t port;
u_int32_t address;
{
struct sockaddr_in name;
int sock;
struct socklist *tmp;
int flag;
name.sin_family = AF_INET;
name.sin_port = port;
name.sin_addr.s_addr = address;
memset (name.sin_zero, 0, sizeof (name.sin_zero));
/* List addresses on which we're listening. */
note ("Receiving on %s, port %d",
inet_ntoa (name.sin_addr), htons (name.sin_port));
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
error ("Can't create dhcp socket: %m");
flag = 1;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
&flag, sizeof flag) < 0)
error ("Can't set SO_REUSEADDR option on dhcp socket: %m");
if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
&flag, sizeof flag) < 0)
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
error ("Can't bind to dhcp address: %m");
tmp = (struct socklist *)dmalloc (sizeof (struct socklist),
"listen_on");
if (!tmp)
error ("Can't allocate memory for socket list.");
tmp -> addr = name;
tmp -> sock = sock;
tmp -> next = sockets;
sockets = tmp;
}
unsigned char packbuf [65536]; /* Should cover the gnarliest MTU... */
void dispatch ()
{
struct sockaddr_in from;
int fromlen = sizeof from;
fd_set r, w, x;
struct socklist *l;
int max = 0;
int count;
int result;
FD_ZERO (&r);
FD_ZERO (&w);
FD_ZERO (&x);
do {
/* Set up the read mask. */
for (l = sockets; l; l = l -> next) {
FD_SET (l -> sock, &r);
FD_SET (l -> sock, &x);
if (l -> sock > max)
max = l -> sock;
}
/* Wait for a packet or a timeout... XXX */
count = select (max + 1, &r, &w, &x, (struct timeval *)0);
/* Not likely to be transitory... */
if (count < 0)
error ("select: %m");
for (l = sockets; l; l = l -> next) {
if (!FD_ISSET (l -> sock, &r))
continue;
if ((result =
recvfrom (l -> sock, packbuf, sizeof packbuf, 0,
(struct sockaddr *)&from, &fromlen))
< 0) {
warn ("recvfrom failed on %s: %m",
inet_ntoa (l -> addr.sin_addr));
sleep (5);
continue;
}
note ("request from %s, port %d",
inet_ntoa (from.sin_addr),
htons (from.sin_port));
do_packet (packbuf, result, &from, fromlen, l -> sock);
}
} while (1);
}

414
common/tables.c Normal file
View File

@ -0,0 +1,414 @@
/* tables.c
Tables of information... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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,
"name-servers", "IA", &dhcp_universe, 5,
"domain-name-servers", "IA", &dhcp_universe, 6,
"log-servers", "IA", &dhcp_universe, 7,
"cookie-servers", "IA", &dhcp_universe, 8,
"lpr-servers", "IA", &dhcp_universe, 9,
"impress-servers", "IA", &dhcp_universe, 10,
"resource-location-servers", "IA", &dhcp_universe, 11,
"host-name", "t", &dhcp_universe, 12,
"boot-size", "S", &dhcp_universe, 13,
"merit-dump", "t", &dhcp_universe, 14,
"domain-name", "t", &dhcp_universe, 15,
"swap-server", "I", &dhcp_universe, 16,
"root-path", "t", &dhcp_universe, 17,
"extensions-path", "t", &dhcp_universe, 18,
"ip-forwarding", "f", &dhcp_universe, 19,
"non-local-source-routing", "f", &dhcp_universe, 20,
"policy-filter", "IIA", &dhcp_universe, 21,
"max-dgram-reassembly", "S", &dhcp_universe, 22,
"default-ip-ttl", "B", &dhcp_universe, 23,
"path-mtu-aging-timeout", "L", &dhcp_universe, 24,
"path-mtu-plateau-table", "SA", &dhcp_universe, 25,
"interface-mtu", "S", &dhcp_universe, 26,
"all-subnets-local", "f", &dhcp_universe, 27,
"broadcast-address", "I", &dhcp_universe, 28,
"perform-mask-discovery", "f", &dhcp_universe, 29,
"mask-supplier", "f", &dhcp_universe, 30,
"router-discovery", "f", &dhcp_universe, 31,
"router-solicitation-address", "I", &dhcp_universe, 32,
"static-routes", "IIA", &dhcp_universe, 33,
"trailer-encapsulation", "f", &dhcp_universe, 34,
"arp-cache-timeout", "L", &dhcp_universe, 35,
"ieee802.3-encapsulation", "f", &dhcp_universe, 36,
"default-tcp-ttl", "B", &dhcp_universe, 37,
"tcp-keepalive-interval", "L", &dhcp_universe, 38,
"tcp-keepalive-garbage", "f", &dhcp_universe, 39,
"nis-domain", "t", &dhcp_universe, 40,
"nis-servers", "IA", &dhcp_universe, 41,
"ntp-servers", "IA", &dhcp_universe, 42,
"vendor-encapsulated-options", "t", &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", "t", &dhcp_universe, 61,
"option-62", "", &dhcp_universe, 62,
"option-63", "", &dhcp_universe, 63,
"option-64", "", &dhcp_universe, 64,
"option-65", "", &dhcp_universe, 65,
"option-66", "", &dhcp_universe, 66,
"option-67", "", &dhcp_universe, 67,
"option-68", "", &dhcp_universe, 68,
"option-69", "", &dhcp_universe, 69,
"option-70", "", &dhcp_universe, 70,
"option-71", "", &dhcp_universe, 71,
"option-72", "", &dhcp_universe, 72,
"option-73", "", &dhcp_universe, 73,
"option-74", "", &dhcp_universe, 74,
"option-75", "", &dhcp_universe, 75,
"option-76", "", &dhcp_universe, 76,
"option-77", "", &dhcp_universe, 77,
"option-78", "", &dhcp_universe, 78,
"option-79", "", &dhcp_universe, 79,
"option-80", "", &dhcp_universe, 80,
"option-81", "", &dhcp_universe, 81,
"option-82", "", &dhcp_universe, 82,
"option-83", "", &dhcp_universe, 83,
"option-84", "", &dhcp_universe, 84,
"option-85", "", &dhcp_universe, 85,
"option-86", "", &dhcp_universe, 86,
"option-87", "", &dhcp_universe, 87,
"option-88", "", &dhcp_universe, 88,
"option-89", "", &dhcp_universe, 89,
"option-90", "", &dhcp_universe, 90,
"option-91", "", &dhcp_universe, 91,
"option-92", "", &dhcp_universe, 92,
"option-93", "", &dhcp_universe, 93,
"option-94", "", &dhcp_universe, 94,
"option-95", "", &dhcp_universe, 95,
"option-96", "", &dhcp_universe, 96,
"option-97", "", &dhcp_universe, 97,
"option-98", "", &dhcp_universe, 98,
"option-99", "", &dhcp_universe, 99,
"option-100", "", &dhcp_universe, 100,
"option-101", "", &dhcp_universe, 101,
"option-102", "", &dhcp_universe, 102,
"option-103", "", &dhcp_universe, 103,
"option-104", "", &dhcp_universe, 104,
"option-105", "", &dhcp_universe, 105,
"option-106", "", &dhcp_universe, 106,
"option-107", "", &dhcp_universe, 107,
"option-108", "", &dhcp_universe, 108,
"option-109", "", &dhcp_universe, 109,
"option-110", "", &dhcp_universe, 110,
"option-111", "", &dhcp_universe, 111,
"option-112", "", &dhcp_universe, 112,
"option-113", "", &dhcp_universe, 113,
"option-114", "", &dhcp_universe, 114,
"option-115", "", &dhcp_universe, 115,
"option-116", "", &dhcp_universe, 116,
"option-117", "", &dhcp_universe, 117,
"option-118", "", &dhcp_universe, 118,
"option-119", "", &dhcp_universe, 119,
"option-120", "", &dhcp_universe, 120,
"option-121", "", &dhcp_universe, 121,
"option-122", "", &dhcp_universe, 122,
"option-123", "", &dhcp_universe, 123,
"option-124", "", &dhcp_universe, 124,
"option-125", "", &dhcp_universe, 125,
"option-126", "", &dhcp_universe, 126,
"option-127", "", &dhcp_universe, 127,
"option-128", "", &dhcp_universe, 128,
"option-129", "", &dhcp_universe, 129,
"option-130", "", &dhcp_universe, 130,
"option-131", "", &dhcp_universe, 131,
"option-132", "", &dhcp_universe, 132,
"option-133", "", &dhcp_universe, 133,
"option-134", "", &dhcp_universe, 134,
"option-135", "", &dhcp_universe, 135,
"option-136", "", &dhcp_universe, 136,
"option-137", "", &dhcp_universe, 137,
"option-138", "", &dhcp_universe, 138,
"option-139", "", &dhcp_universe, 139,
"option-140", "", &dhcp_universe, 140,
"option-141", "", &dhcp_universe, 141,
"option-142", "", &dhcp_universe, 142,
"option-143", "", &dhcp_universe, 143,
"option-144", "", &dhcp_universe, 144,
"option-145", "", &dhcp_universe, 145,
"option-146", "", &dhcp_universe, 146,
"option-147", "", &dhcp_universe, 147,
"option-148", "", &dhcp_universe, 148,
"option-149", "", &dhcp_universe, 149,
"option-150", "", &dhcp_universe, 150,
"option-151", "", &dhcp_universe, 151,
"option-152", "", &dhcp_universe, 152,
"option-153", "", &dhcp_universe, 153,
"option-154", "", &dhcp_universe, 154,
"option-155", "", &dhcp_universe, 155,
"option-156", "", &dhcp_universe, 156,
"option-157", "", &dhcp_universe, 157,
"option-158", "", &dhcp_universe, 158,
"option-159", "", &dhcp_universe, 159,
"option-160", "", &dhcp_universe, 160,
"option-161", "", &dhcp_universe, 161,
"option-162", "", &dhcp_universe, 162,
"option-163", "", &dhcp_universe, 163,
"option-164", "", &dhcp_universe, 164,
"option-165", "", &dhcp_universe, 165,
"option-166", "", &dhcp_universe, 166,
"option-167", "", &dhcp_universe, 167,
"option-168", "", &dhcp_universe, 168,
"option-169", "", &dhcp_universe, 169,
"option-170", "", &dhcp_universe, 170,
"option-171", "", &dhcp_universe, 171,
"option-172", "", &dhcp_universe, 172,
"option-173", "", &dhcp_universe, 173,
"option-174", "", &dhcp_universe, 174,
"option-175", "", &dhcp_universe, 175,
"option-176", "", &dhcp_universe, 176,
"option-177", "", &dhcp_universe, 177,
"option-178", "", &dhcp_universe, 178,
"option-179", "", &dhcp_universe, 179,
"option-180", "", &dhcp_universe, 180,
"option-181", "", &dhcp_universe, 181,
"option-182", "", &dhcp_universe, 182,
"option-183", "", &dhcp_universe, 183,
"option-184", "", &dhcp_universe, 184,
"option-185", "", &dhcp_universe, 185,
"option-186", "", &dhcp_universe, 186,
"option-187", "", &dhcp_universe, 187,
"option-188", "", &dhcp_universe, 188,
"option-189", "", &dhcp_universe, 189,
"option-190", "", &dhcp_universe, 190,
"option-191", "", &dhcp_universe, 191,
"option-192", "", &dhcp_universe, 192,
"option-193", "", &dhcp_universe, 193,
"option-194", "", &dhcp_universe, 194,
"option-195", "", &dhcp_universe, 195,
"option-196", "", &dhcp_universe, 196,
"option-197", "", &dhcp_universe, 197,
"option-198", "", &dhcp_universe, 198,
"option-199", "", &dhcp_universe, 199,
"option-200", "", &dhcp_universe, 200,
"option-201", "", &dhcp_universe, 201,
"option-202", "", &dhcp_universe, 202,
"option-203", "", &dhcp_universe, 203,
"option-204", "", &dhcp_universe, 204,
"option-205", "", &dhcp_universe, 205,
"option-206", "", &dhcp_universe, 206,
"option-207", "", &dhcp_universe, 207,
"option-208", "", &dhcp_universe, 208,
"option-209", "", &dhcp_universe, 209,
"option-210", "", &dhcp_universe, 210,
"option-211", "", &dhcp_universe, 211,
"option-212", "", &dhcp_universe, 212,
"option-213", "", &dhcp_universe, 213,
"option-214", "", &dhcp_universe, 214,
"option-215", "", &dhcp_universe, 215,
"option-216", "", &dhcp_universe, 216,
"option-217", "", &dhcp_universe, 217,
"option-218", "", &dhcp_universe, 218,
"option-219", "", &dhcp_universe, 219,
"option-220", "", &dhcp_universe, 220,
"option-221", "", &dhcp_universe, 221,
"option-222", "", &dhcp_universe, 222,
"option-223", "", &dhcp_universe, 223,
"option-224", "", &dhcp_universe, 224,
"option-225", "", &dhcp_universe, 225,
"option-226", "", &dhcp_universe, 226,
"option-227", "", &dhcp_universe, 227,
"option-228", "", &dhcp_universe, 228,
"option-229", "", &dhcp_universe, 229,
"option-230", "", &dhcp_universe, 230,
"option-231", "", &dhcp_universe, 231,
"option-232", "", &dhcp_universe, 232,
"option-233", "", &dhcp_universe, 233,
"option-234", "", &dhcp_universe, 234,
"option-235", "", &dhcp_universe, 235,
"option-236", "", &dhcp_universe, 236,
"option-237", "", &dhcp_universe, 237,
"option-238", "", &dhcp_universe, 238,
"option-239", "", &dhcp_universe, 239,
"option-240", "", &dhcp_universe, 240,
"option-241", "", &dhcp_universe, 241,
"option-242", "", &dhcp_universe, 242,
"option-243", "", &dhcp_universe, 243,
"option-244", "", &dhcp_universe, 244,
"option-245", "", &dhcp_universe, 245,
"option-246", "", &dhcp_universe, 246,
"option-247", "", &dhcp_universe, 247,
"option-248", "", &dhcp_universe, 248,
"option-249", "", &dhcp_universe, 249,
"option-250", "", &dhcp_universe, 250,
"option-251", "", &dhcp_universe, 251,
"option-252", "", &dhcp_universe, 252,
"option-253", "", &dhcp_universe, 253,
"option-254", "", &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_SUBNET_MASK,
DHO_TIME_OFFSET,
DHO_ROUTERS,
DHO_TIME_SERVERS,
DHO_NAME_SERVERS,
DHO_DOMAIN_NAME_SERVERS,
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_REQUESTED_ADDRESS,
DHO_DHCP_LEASE_TIME,
DHO_DHCP_OPTION_OVERLOAD,
DHO_DHCP_MESSAGE_TYPE,
DHO_DHCP_SERVER_IDENTIFIER,
DHO_DHCP_PARAMETER_REQUEST_LIST,
DHO_DHCP_MESSAGE,
DHO_DHCP_MAX_MESSAGE_SIZE,
DHO_DHCP_RENEWAL_TIME,
DHO_DHCP_REBINDING_TIME,
DHO_DHCP_CLASS_IDENTIFIER,
DHO_DHCP_CLIENT_IDENTIFIER,
};
int sizeof_dhcp_option_default_priority_list =
sizeof dhcp_option_default_priority_list;
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, dhcp_options [i].name, 0,
(unsigned char *)&dhcp_options [i]);
}
universe_hash.hash_count = DEFAULT_HASH_SIZE;
add_hash (&universe_hash, dhcp_universe.name, 0,
(unsigned char *)&dhcp_universe);
}

391
common/tree.c Normal file
View File

@ -0,0 +1,391 @@
/* tree.c
Routines for manipulating parse 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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 = (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 -> 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;
debug ("time: now = %d dns = %d %d diff = %d",
cur_time, dns -> timeout, cur_time - dns -> timeout);
/* If the record hasn't timed out, just copy the data and return. */
if (cur_time <= dns -> timeout) {
debug ("easy copy: %x %d %x",
dns -> data, dns -> data_len, *(int *)(dns -> data));
do_data_copy (bufix, bufp, bufcount,
dns -> data, dns -> data_len);
return dns -> timeout;
}
debug ("Looking up %s", dns -> hostname);
/* Otherwise, look it up... */
h = gethostbyname (dns -> hostname);
if (!h) {
switch (h_errno) {
case HOST_NOT_FOUND:
warn ("%s: host unknown.", dns -> hostname);
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);
}
/* Okay to try again after a minute. */
return cur_time + 60;
}
debug ("Lookup succeeded; first address is %x",
h -> h_addr_list [0]);
/* 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 {
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);
debug ("dns -> data: %x h -> h_addr_list [0]: %x",
*(int *)(dns -> data), h -> h_addr_list [0]);
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;
debug ("hard copy: %x %d %x",
dns -> data, dns -> data_len, *(int *)(dns -> data));
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;
}

114
conf.y Normal file
View File

@ -0,0 +1,114 @@
/* conf.y
Dhcpd configuration file grammar... */
/*
* 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''.
*/
%{
#include "dhcpd.h"
%}
%token HOST HARDWARE ETHERNET FILENAME FIXED_ADDRESS STRING
%token OCTET COLON DOT SEMI TOKEN OPTION
%start config
%%
config : config_items
;
config_items: /* blank */
| config_item
| config_items config_item
;
config_item: host_decl
;
host_decl: HOST hostname packet_decls SEMI
;
hostname: token
| token DOT hostname
;
packet_decls: /* empty */
| packet_decl
| packet_decls packet_decl
;
packet_decl: hardware_decl
| filename_decl
| fixed_addr_decl
| option_decl
;
hardware_decl: HARDWARE ETHERNET OCTET COLON OCTET COLON OCTET
COLON OCTET COLON OCTET COLON OCTET
;
filename_decl: FILENAME STRING
;
fixed_addr_decl: FIXED_ADDRESS host_address
;
host_address: hostname
| ip_address
;
ip_address: OCTET DOT OCTET
| OCTET DOT OCTET DOT OCTET DOT OCTET
;
option_decl: OPTION token STRING
;
token: reserved_word
| TOKEN
;
reserved_word: HOST
| HARDWARE
| ETHERNET
| FILENAME
| FIXED_ADDRESS
| OPTION
;

280
conflex.c Normal file
View File

@ -0,0 +1,280 @@
/* conflex.c
Lexical scanner for dhcpd config file... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include "dhctoken.h"
#include <ctype.h>
static int line;
static int lpos;
int tlpos;
int tline;
static int token;
static int ugflag;
static char *tval;
static char tokbuf [1500];
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_atom PROTO ((int, FILE *));
static int intern PROTO ((char *, int));
static int get_char (cfile)
FILE *cfile;
{
char c = getc (cfile);
if (!ugflag) {
if (c == EOL) {
line++;
lpos = 1;
} else {
lpos++;
}
} else
ugflag = 0;
return c;
}
static int get_token (cfile)
FILE *cfile;
{
int c;
int i;
int ttok;
do {
c = get_char (cfile);
if (isascii (c) && isspace (c))
continue;
if (c == '#') {
skip_to_eol (cfile);
continue;
}
tlpos = lpos;
tline = line;
if (c == '"') {
ttok = read_string (cfile);
break;
}
if (isascii (c) && isdigit (c)) {
ttok = read_number (c, cfile);
break;
} else if (isascii (c) && isalpha (c)) {
ttok = read_num_or_atom (c, cfile);
break;
} else {
tval = 0;
ttok = c;
break;
}
} while (1);
return ttok;
}
int next_token (rval, cfile)
char **rval;
FILE *cfile;
{
int rv;
if (token) {
rv = token;
token = 0;
} else {
rv = get_token (cfile);
}
if (rval)
*rval = tval;
return rv;
}
int peek_token (rval, cfile)
char **rval;
FILE *cfile;
{
if (!token)
token = get_token (cfile);
if (rval)
*rval = tval;
return token;
}
static void skip_to_eol (cfile)
FILE *cfile;
{
int c;
do {
c = get_char (cfile);
if (c == EOF)
return;
if (c == EOL) {
ungetc (c, cfile);
ugflag = 1;
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;
tokbuf [i++] = c;
for (; i < sizeof tokbuf; i++) {
c = get_char (cfile);
if (!seenx && c == 'x')
seenx = 1;
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 NUMBER;
}
static int read_num_or_atom (c, cfile)
int c;
FILE *cfile;
{
int i = 0;
int rv = NUMBER_OR_ATOM;
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 = ATOM;
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;
{
switch (atom [0]) {
case 'h':
if (!strcasecmp (atom + 1, "ost"))
return HOST;
if (!strcasecmp (atom + 1, "ardware"))
return HARDWARE;
break;
case 'f':
if (!strcasecmp (atom + 1, "ilename"))
return FILENAME;
if (!strcasecmp (atom + 1, "ixed-address"))
return FIXED_ADDR;
break;
case 'e':
if (!strcasecmp (atom + 1, "thernet"))
return ETHERNET;
break;
case 'o':
if (!strcasecmp (atom + 1, "ption"))
return OPTION;
break;
}
return dfv;
}

1048
confpars.c Normal file

File diff suppressed because it is too large Load Diff

117
convert.c Normal file
View File

@ -0,0 +1,117 @@
/* 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 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[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
unsigned long getULong (buf)
unsigned char *buf;
{
unsigned long ibuf;
memcpy (&ibuf, buf, sizeof (unsigned long));
return ntohl (ibuf);
}
long getLong (buf)
unsigned char *buf;
{
long ibuf;
memcpy (&ibuf, buf, sizeof (long));
return ntohl (ibuf);
}
unsigned short getUShort (buf)
unsigned char *buf;
{
unsigned short ibuf;
memcpy (&ibuf, buf, sizeof (unsigned short));
return ntohs (ibuf);
}
short getShort (buf)
unsigned char *buf;
{
short ibuf;
memcpy (&ibuf, buf, sizeof (short));
return ntohs (ibuf);
}
void putULong (obuf, val)
unsigned char *obuf;
unsigned long val;
{
unsigned long tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putLong (obuf, val)
unsigned char *obuf;
long val;
{
long tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putUShort (obuf, val)
unsigned char *obuf;
unsigned short val;
{
unsigned short tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}
void putShort (obuf, val)
unsigned char *obuf;
short val;
{
short tmp = htonl (val);
memcpy (obuf, &tmp, sizeof tmp);
}

142
db.c Normal file
View File

@ -0,0 +1,142 @@
/* db.c
IP Address Allocation database... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
/*
The IP Address Allocation Database tracks addresses that have been
allocated from the free pool as specified in dhcpd.conf. The
database is maintained in two parts to maintain integrity: the
journal file and the data file.
Both files are free-form flat files similar to dhcpd.conf, but with
a more limited syntax - all that can be specified are leases and
who they belong to.
When dhcpd starts up, it reads the entire data file into memory.
It then reads the journal file into memory and makes corrections to
the data based on journal entries.
While dhcpd is running, it periodically records the current time,
forks (if possible) and dumps the recorded time and its internal
database of temporarily assigned addresses into a temporary file.
It then removes any existing backup file, renames the existing file
with the backup filename, and then renames the new temporary file
with the real data file name. The link syscall is not present on
most systems, so a synchronous ``rename'' that guarantees that
exactly one file will be the master database may not be possible.
Therefore the recovery routine needs to know what to do if it finds
a backup and a temporary file, but no database file.
Whenever a client requests that an address be allocated to it, or
requests a lease renewal, and the server is able to satisfy the
request, it writes a record into the journal file indicating what
has been requested and waits for that information to reach the
disk. Once the file's dirty buffers have been flushed, the server
responds to the request, and logs another record in the journal
indicating that it has done so.
Entries in the journal file are logged along with the time at which
the logging occurred. When the server forks to dump the database,
it records the current time before forking. The copy of the server
that writes out the database records the time read prior to forking
in the new data file. The copy of the server that continues to
serve DHCP requests ensures that any journal entries subsequent to
the fork have time stamps that are greater than the time read
before forking. When recovering from a crash, the server discards
any entries in the journal which have time stamps earlier than the
time stamp on the data file.
When recovering from a crash, dhcpd may find a journal entry for a
request, but no entry indicating that it was satisfied. There is
no automatic way to recover from this, since the server may have
sent out a response, so in this case the server must notify
sysadmin of the problem and leave it to them to solve it.
In addition to the actual data files, we also keep a running log of
``interesting'' events, which we mail to the dhcp-admin alias every
morning at 7:00 AM. This log can be tailed by paranoid sysadmins
or in times of network trouble. */
/* Initialize the internal database, perform crash recovery as needed. */
void dbinit ()
{
FILE *dbfile;
/* We are assuming that on entry, there is no other dhcpd
running on this machine. If there were, there would be the
potential for serious database corruption. The main code
currently assures that there is only one server running by
listening on the bootps port with INADDR_ANY. Unices that
I'm familiar with will only allow one process to do this,
even if the SO_REUSEADDR option is set. 'twouldn't surprise
me terribly, though, if this didn't work for some other
operating system. Beware. XXX */
/* Look for a file under the official database name.
Failing that, look for a file under the backup name.
If we find neither, we assume that the database is empty. */
if ((dbfile = fopen (_PATH_DHCP_DB, "r")) != NULL
(dbfile = fopen (_PATH_DHCP_DB_BACKUP, "r") != NULL)) {
/* Read in the data file, making a list of assigned
addresses that have been removed from dhcpd.conf. */
}
/* Open the journal file and read through any entries which
are out of date. */
/* Now read entries that postdate the last database sync,
keeping track of incomplete entries (when we're done, there
should never be more than one such entry. */
/* Now expire any leases that have lapsed since we last ran. */
/* ...and we're done... */
}

52
dhcp.c Normal file
View File

@ -0,0 +1,52 @@
/* dhcp.c
DHCP Protocol support. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
void dhcp (packet)
struct packet *packet;
{
}

155
dhcp.h Normal file
View File

@ -0,0 +1,155 @@
/* dhcp.h
Protocol structures... */
/*
* 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''.
*/
#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_LEN (236 + DHCP_UDP_OVERHEAD) /* Everything but
options. */
#define DHCP_MTU_MAX 1500
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
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 */
char chaddr [16]; /* Client hardware address */
char sname [64]; /* Server name */
char file [128]; /* Boot filename */
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
/* 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_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

256
dhcpd.c Normal file
View File

@ -0,0 +1,256 @@
/* dhcpd.c
DHCP Server Daemon. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static void usage PROTO ((void));
TIME cur_time;
u_int32_t *server_addrlist;
int server_addrcount;
u_int16_t server_port;
int main (argc, argv, envp)
int argc;
char **argv, **envp;
{
struct in_addr addr;
int port = 0;
int i;
struct sockaddr_in name;
u_int32_t *addrlist = (u_int32_t *)0;
int addrcount = 0;
struct tree *addrtree = (struct tree *)0;
struct servent *ent;
int sock;
int pid;
int result;
int flag;
openlog ("dhcpd", LOG_NDELAY, LOG_DAEMON);
#ifndef DEBUG
setlogmask (LOG_UPTO (LOG_INFO));
/* Become a daemon... */
if ((pid = fork ()) < 0)
error ("Can't fork daemon: %m");
else if (pid)
exit (0);
/* Become session leader and get pid... */
pid = setsid ();
#endif
for (i = 1; i < argc; i++) {
if (!strcmp (argv [i], "-p")) {
if (++i == argc)
usage ();
server_port = htons (atoi (argv [i]));
debug ("binding to user-specified port %d\n",
ntohs (server_port));
#if 0
} else if (!strcmp (argv [i], "-a")) {
if (++i == argc)
usage ();
if (inet_aton (argv [i], &addr)) {
addrtree =
tree_concat (addrtree,
tree_const
((unsigned char *)&addr,
sizeof addr));
} else {
addrtree = tree_concat (addrtree,
tree_host_lookup
(argv [i]));
}
#endif
} else
usage ();
}
/* Default to the DHCP/BOOTP port. */
if (!server_port)
{
ent = getservbyname ("dhcp", "udp");
if (!ent)
server_port = htons (67);
else
server_port = ent -> s_port;
endservent ();
}
/* Get the current time... */
GET_TIME (&cur_time);
/* Read the dhcpd.conf file... */
readconf ();
#if 0
/* If addresses were specified on the command line, resolve them;
otherwise, just get a list of the addresses that are configured
on this host and listen on all of them. */
if (addrtree) {
tree_evaluate ((unsigned char **)&addrlist,
&addrcount, addrtree);
addrcount /= 4;
if (!addrcount)
error ("Server addresses resolve to nothing.");
} else {
/* addrlist = get_interface_list (&addrcount); */
#endif
addr.s_addr = 0;
addrlist = (u_int32_t *)&(addr.s_addr);
addrcount = 1;
#if 0
}
#endif
server_addrlist = get_interface_list (&server_addrcount);
/* Listen on the specified (or default) port on each specified
(or default) IP address. */
for (i = 0; i < addrcount; i++) {
listen_on (server_port, addrlist [i]);
}
/* Write a pid file. */
if ((i = open (_PATH_DHCPD_PID, O_WRONLY | O_CREAT)) >= 0) {
char obuf [20];
sprintf (obuf, "%d\n", getpid ());
write (i, obuf, strlen (obuf));
close (i);
}
/* Receive packets and dispatch them... */
dispatch ();
}
/* Print usage message. */
static void usage ()
{
error ("Usage: dhcpd [-p <port>] [-a <ip-addr>]");
}
void cleanup ()
{
}
void do_packet (packbuf, len, from, fromlen, sock)
unsigned char *packbuf;
int len;
struct sockaddr_in *from;
int fromlen;
int sock;
{
struct packet *tp;
struct dhcp_packet *tdp;
if (!(tp = new_packet ("do_packet")))
return;
if (!(tdp = new_dhcp_packet ("do_packet"))) {
free_packet (tp, "do_packet");
return;
}
memcpy (tdp, packbuf, len);
memset (tp, 0, sizeof *tp);
tp -> raw = tdp;
tp -> packet_length = len;
tp -> client = *from;
tp -> client_len = fromlen;
tp -> client_sock = sock;
parse_options (tp);
if (tp -> options_valid &&
tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
dhcp (tp);
else
bootp (tp);
}
dump_packet (tp)
struct packet *tp;
{
struct dhcp_packet *tdp = tp -> raw;
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 yiaddr = %s",
inet_ntoa (tdp -> ciaddr), inet_ntoa (tdp -> yiaddr));
debug ("siaddr = %s giaddr = %s",
inet_ntoa (tdp -> siaddr), 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]);
if (tp -> options_valid) {
int i;
for (i = 0; i < 256; i++) {
if (tp -> options [i].data)
printf (" %s = %s\n",
dhcp_options [i].name,
pretty_print_option
(i, tp -> options [i].data,
tp -> options [i].len));
}
}
}
/* Based on the contents of packet, figure out which interface address
to use from server_addrlist. Currently just picks the first
interface. */
u_int32_t pick_interface (packet)
struct packet *packet;
{
if (server_addrlist)
return server_addrlist [0];
return 0;
}

17
dhcpd.conf Normal file
View File

@ -0,0 +1,17 @@
host minuet
hardware ethernet 08:00:2b:35:0c:18
filename "/tftpboot/netbsd.minuet"
fixed-address minuet.fugue.com;
host allegro
hardware ethernet 08:00:2b:1c:07:b6
filename "/tftpboot/netbsd.allegro"
fixed-address allegro.fugue.com;
host fantasia
hardware ethernet 8:0:7:26:c0:a5
fixed-address fantasia.fugue.com
option routers prelude.fugue.com
option name-servers toccata.fugue.com, passacaglia.fugue.com
option domain-name "fugue.com";

263
dhcpd.h Normal file
View File

@ -0,0 +1,263 @@
/* dhcpd.h
Definitions for dhcpd... */
/*
* 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''.
*/
#include <sys/types.h>
#include <syslog.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <stdio.h>
#include "dhcp.h"
#include "cdefs.h"
#include "osdep.h"
#include "tree.h"
#include "hash.h"
/* 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;
struct sockaddr_in client;
int client_len;
int client_sock;
struct {
int len;
unsigned char *data;
} options [256];
};
struct hardware {
u_int8_t htype;
u_int8_t hlen;
u_int8_t haddr [16];
};
/* A dhcp host declaration structure. */
struct host_decl {
struct host_decl *n_name, *n_haddr, *n_cid;
char *name;
struct hardware *interfaces;
int interface_count;
char *filename;
char *server_name;
struct tree_cache *fixed_addr;
struct tree_cache *options [256];
};
/* A dhcp lease declaration structure. */
struct lease {
struct lease *next;
struct lease *prev;
struct in_addr ip_addr;
TIME starts, ends, timestamp;
unsigned char *uid;
int uid_len;
struct host_decl *host;
struct subnet *contain;
struct hardware hardware_addr;
int state;
};
struct subnet {
struct in_addr net;
struct in_addr netmask;
struct lease *leases;
struct lease *insertion_point;
};
/* 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. */
#ifndef _PATH_DHCPD_CONF
#ifdef DEBUG
#define _PATH_DHCPD_CONF "dhcpd.conf"
#else
#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
#endif
#endif
/* Subnet macros... */
#define SUBNET(addr, mask) ((addr).s_addr & (netmask).s_addr)
#define IP_ADDR(net, host) ((net).s_addr | i)
#define HOST_ADDR(addr, mask) ((addr).s_addr & ~(netmask).s_addr)
#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));
void cons_options PROTO ((struct packet *, struct dhcp_packet *,
struct host_decl *, int));
char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
/* errwarn.c */
int error PROTO ((char *, ...));
int warn PROTO ((char *, ...));
int note PROTO ((char *, ...));
int debug PROTO ((char *, ...));
int parse_warn PROTO ((char *, ...));
/* dhcpd.c */
TIME cur_time;
extern u_int32_t *server_addrlist;
extern int server_addrcount;
extern u_int16_t server_port;
int main PROTO ((int, char **, char **));
void cleanup PROTO ((void));
void do_packet PROTO ((unsigned char *, int, struct sockaddr_in *, int, int));
u_int32_t pick_interface PROTO ((struct packet *));
/* conflex.c */
int next_token PROTO ((char **, FILE *));
int peek_token PROTO ((char **, FILE *));
/* confpars.c */
void readconf PROTO ((void));
void parse_statement PROTO ((FILE *));
void skip_to_semi PROTO ((FILE *));
struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
char *parse_host_name PROTO ((FILE *, jmp_buf *));
void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
void parse_option_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
TIME parse_date PROTO ((FILE *, jmp_buf *));
struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
void parse_address_range PROTO ((FILE *, jmp_buf *));
unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
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 */
void dhcp PROTO ((struct packet *));
/* bootp.c */
void bootp PROTO ((struct packet *));
/* memory.c */
void enter_host PROTO ((struct host_decl *));
struct host_decl *find_host_by_name PROTO ((char *name));
struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
extern struct subnet *find_subnet (struct in_addr);
void enter_subnet (struct subnet *);
void enter_lease PROTO ((struct lease *));
void supersede_lease PROTO ((struct lease *, struct lease *));
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
struct lease *find_lease_by_ip_addr PROTO ((struct in_addr));
struct lease *find_next_expiring_lease 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 (int, char *);
struct subnet *new_subnet PROTO ((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 *));
/* socket.c */
u_int32_t *get_interface_list PROTO ((int *));
void listen_on PROTO ((u_int16_t, u_int32_t));
void dispatch PROTO ((void));
/* hash.c */
struct hash_table *new_hash PROTO ((void));
void add_hash PROTO ((struct hash_table *, char *, int, unsigned char *));
void delete_hash_entry PROTO ((struct hash_table *, char *, int));
unsigned char *hash_lookup PROTO ((struct hash_table *, 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 struct hash_table universe_hash;
extern struct universe dhcp_universe;
void initialize_universes PROTO ((void));

71
dhctoken.h Normal file
View File

@ -0,0 +1,71 @@
/* dhctoken.h
Tokens for config file lexer and parser. */
/*
* 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''.
*/
#define SEMI ';'
#define DOT '.'
#define COLON ':'
#define COMMA ','
#define SLASH '/'
#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_ATOM 264
#define ATOM 265
#define TIMESTAMP 266
#define STARTS 267
#define ENDS 268
#define UID 269
#define CLASS 270
#define LEASE 271
#define RANGE 272
#define LAST_TOKEN RANGE
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
(x) <= FIRST_TOKEN && \
(x) != STRING && \
(x) != NUMBER)

188
doc/dhc-minutes-94dec.txt Normal file
View File

@ -0,0 +1,188 @@
CURRENT_MEETING_REPORT_
Reported by Walt Wimer/CMU
Minutes of the Dynamic Host Configuration Working Group (DHC)
The DHC Working Group met on 7 December and 9 December at the 31st IETF.
Document Status
The most recent Internet-Draft of the DHCP specification includes
several changes based on the results of the latest interoperability
testing. Based on the results of that testing, and a review of the
Standards process RFC, the working group decided it would be appropriate
to ask that DHCP be considered for ``Draft Standard'' status. As soon
as a revision of the current Internet-Draft is completed, the
specification for DHCP will be submitted for review.
A few, minor changes have been made to RFC 1541 based on questions
raised during the latest interoperability testing. Two new options have
been defined since RFC 1533: 62, NetWare/IP domain and 63, NetWare/IP
option.
The working group agreed that the minimum lease requirement (one hour)
should be made advisory rather than mandatory.
Implementations
The following list of implementations was compiled from information
given by working group attendees.
_____________________________________________________________________
|| | | | ||
|| Vendor |Client |Server |Relay agent ||
||___________________|___________________|_______________|_____________||
|| FTP Software |DOS/Windows |Windows | ||
||___________________|___________________|NT_(beta)______|_____________||
|| SunSoft |DOS/Windows |Solaris 2.0 |in server ||
||___________________|Solaris_(beta?)____|_______________|_____________||
|| Microsoft |DOS/Windows |NT |in server ||
|| |NT | | ||
||___________________|Windows95_beta_____|_______________|_____________||
|| Competitive |??? |Solaris | ||
||_Automation________|___________________|_______________|_____________||
|| Apple |Newton | | ||
||___________________|Mac_(beta)_________|_______________|_____________||
|| WIDE project |Unix, BSD386 |Unix, BSD386 |Unix, BSD386 ||
||_(free,_avail_2/95)|News,_SunOS________|News,_SunOS____|News,_SunOS_ ||
||_Silicon_Graphics__|IRIX_(soon)________|IRIX___________|_____________||
|| Hewlett Packard |X-terminal |HP/UX (June 95)|in server ||
||___________________|___________________|_______________|HP_router____||
|| IBM |OS/2 (soon) |OS/2 (soon) | ||
|| |AIX (soon) |AIX (soon) | ||
||___________________|___________________|AS/400_(soon)__|_____________||
|| cisco Systems |Terminal server? | |routers ||
|| |(proxy for | | ||
||___________________|terminal_clients?)_|_______________|_____________||
|| Novell |NetWare/IP |NetWare/IP | ||
||___________________|(spring)___________|(later)________|_____________||
|| Shiva |Proxy for | | ||
||___________________|dial-in_clients____|_______________|_____________||
Future Interoperability Test
There was some discussion of a future interoperability test. Suggested
venues include Bucknell University (summer '95), CMU (no specific time),
next IETF (March '95) and remote via the Internet (?!?!). The working
group will hold a discussion about the next interoperability testing via
electronic mail.
Outstanding Issues
The working group discussed some outstanding issues and generated some
solutions:
o New options: TFTP server address, bootfile name, to be registered
with IANA.
o Some clients will already have an IP address, not otherwise
registered or managed by DHCP. Those clients will only want local
configuration parameters, not an address. A new DHCP message,
DHCPINFORM, will be defined for parameter requests.
o There was some question about the definition and interpretation of
``client identifiers.'' The working group confirmed that a
``client identifier'' is an opaque, unique identifier. Text will
be added to the protocol specification to clarify this issue and to
advise that ``client identifiers'' must be unique. ``Client
identifier'' type 0 will indicate ``an opaque string of
characters.''
The issue of security was discussed. The primary concern is to detect
and avoid spoof/unauthorized servers. Some sites are also concerned
about unauthorized clients. The consensus was that a public key
identification and authorization mechanism should be developed as an
optional DHCP service.
Ralph Droms presented a preliminary proposal for a server-server
protocol to allow automatic management of DHCP bindings by multiple DHCP
servers at a single site. The goals are to increase availability and
reliability through redundancy of address allocation and binding
servers, and through load sharing. The basic model, based on a proposal
by Jeff Mogul, is to assign each allocatable address and allocated
binding to a specific ``owner'' server. That owner has modification
privileges, while all other servers have read-only privileges. Servers
use TCP connections and a simple protocol to replicate copies of new
bindings and transfer ownership of addresses to balance the pool of
available addresses.
The hard part is bindings that are released early, prior to expiration.
Those released bindings must be reported to all other servers, so those
servers do not respond with stale data in the future. However, servers
may be inaccessible. The proposed solution was to add an ``owner''
option; clients would select responses from the ``owner'' in favor of
all other responses.
The suggestion was made that multiple DHCP servers might be able to use
an underlying distributed database like DNS, NIS+ or Oracle. Questions
were raised about the scalability of the proposed scheme -- suppose many
clients send simultaneous update requests, how often should updates be
replicated, what about combinatoric explosion with the number of
servers?
IPv6 Issues
The second meeting began with a discussion of several IPv6 issues. IPv6
address configuration has three basic forms:
1. Intra-link scope address (client forms address all on its own)
2. ``Stateless'' servers (e.g., in routers using some simple
assignment algorithm)
3. Stateful servers (`a la IPv4 DHCP)
Regardless of how addresses are managed, IPv6 will need some other
mechanism(s) to obtain other configuration parameters. Some members of
the IPv6 design team claim there will be no other parameters.
The following action items were identified:
o Someone to enumerate all IPv6 network layer parameters.
Mike Carney volunteered.
o Extensions/changes to DHCP protocol format for IPv6.
Walt Wimer volunteered.
Dynamic Addressing
Next, the working group discussed the problem of dynamic updates to DNS
from DHCP information (dynamic addressing). For simple registration of
DNS hostnames for individual DHCP clients, what should we do? Should
client be responsible for contacting DNS server directly, or should DHCP
server contact DNS on behalf of client? It will be necessary to clarify
DNS configuration/update mechanism with DNS Working Group. One solution
to the question of who does the update would be to define a DHCP option
for client to say whether it will do the registration with DNS directly
or whether client wants DHCP server to take care of it. DHCP server may
need a way to veto the client's preference. This permits a simple
client (such as an embedded hub, probe, etc.) to let the DHCP server do
everything (DHCP server probably has necessary credentials to update DNS
while client probably does not). Or, a more sophisticated client can
update its ``home'' DNS directly (for example, a mobile notebook
computer belonging to XYZ, Inc. can be taken to an IETF get a local IP
address from the IETF DHCP server, but then directly update XYZ.COM's
DNS server in order to maintain an XYZ.COM name). The problem of name
collisions was unresolved - should the client or the server be
responsible? Masataka Ohta volunteered to do a DHCP-to-DNS interaction
proposal
DHCP and SNMP
Finally, the working group considered DHCP and SNMP. The working group
chair asked if there were any MIB writers in the audience. The scribe
thought there was a volunteer but did not catch the name.

267
doc/dns-minutes-93nov.txt Normal file
View File

@ -0,0 +1,267 @@
CURRENT_MEETING_REPORT_
Reported by Rob Austein/Epilogue Technology
Minutes of the Domain Name System Working Group (DNS)
Documents
Three new DNS-related Informational RFCs have come out recently.
RFC 1535 (also known as ``the EDU.COM emergency RFC'') details problems
with a widely-used but ill-advised DNS search heuristic, and proposes a
solution. RFC 1536 details common DNS implementation errors, with
proposed solutions; this document was accepted as a DNS Working Group
project at the 27th IETF (Amsterdam), completed, and accepted on the
mailing list. RFC 1537 details common DNS configuration errors; while
it was never formally accepted as a DNS Working Group document, it was
reviewed by the working group members. These three RFCs are closely
related and cross-reference each other, so, on advice of the RFC Editor,
the DNS Working Group Chair approved ``fast track'' publication of these
documents on behalf of the Working Group. If anybody has serious
problems with these documents, blame it on the Chair.
Dave Perkins reported on the current status of the DNS MIB documents on
behalf of the Network Management Area Directorate (NMDIR). Basically,
there are no remaining hard problems, just some remaining detail work.
One of the authors, Rob Austein, has received a detailed list of
remaining concerns, none of which appear to be show-stoppers. It should
be possible to get these documents out the door before the 29th IETF in
Seattle. Dave pointed out two design issues that are not objections but
of which he thinks the DNS Working Group should be aware:
1. Due to SNMP protocol limitations, the length limits on DNS names
used as indices to ``conceptual tables'' in the MIBs will be
shorter than the DNS name length limit of 255 octets. Based on
analysis of current usage, this should not be a problem, so we'll
flag it with a warning statement in the document but otherwise
leave it alone.
2. The most recent versions of the documents (not yet released as
Internet-Drafts) use the SNMPv2 SMI rather than the SNMPv1 SMI, in
order to clear up some problems with unsigned 32-bit integers.
NMDIR wants to be sure that the DNS Working Group realizes that
this means only SNMPv2-capable implementations will be able to use
these MIBs.
DNS Security Sub-Group
James Galvin gave a report on the meeting held by the DNS Security
``sub-group'' (a spin off from the DNS Working Group at the 26th IETF in
Columbus).
The DNS Security design team of the DNS Working Group met for
one morning at the Houston IETF. The discussion began with a
call for threats that the members of the group were most
concerned about. The list included the following:
o disclosure of the data - some expressed a desire to be
able to encrypt the data in responses
o modification of the data
o masquerade of the origin of the data
o masquerade of a secondary - some expressed a desire to be
able to reliably identify both peers in a zone transfer;
this would provide the basis for controlling access to
zone transfers
During the discussion of these threats it was agreed to accept
the following assumptions:
1. DNS data is ``public''
2. backward/co-existence compatibility is required
With respect to the first, accepting it set aside any further
discussion of the threat of disclosure of the data. The second
assumption is included explicitly to remind everyone that we do
not want parallel DNS systems in the Internet.
In addition, it was explicitly agreed that we would not address
authentication of secondaries or access control issues. Thus,
the current list of desired security services is:
o data integrity
o data origin authentication
It was noted that a digital signature mechanism would support
the desired services.
The meeting continued with a brainstorming period during which
the desired functional requirements of a secure DNS were
collected. This list does not represent mandatory
functionality but, rather, it is desired functionality. It was
agreed that this list was subject to discussion on the mailing
list for a period of time that would conclude on November 30.
The requirements are listed here in no particular order.
o sites must be able to support at least their internal
users in the presence of external network failures
o it should be possible for a site to pre-configure other
authoritative servers without having to query the
``system'' to find the server
o it should be possible to request services only from
security enhanced servers, only from non-security enhanced
servers, or to indicate that either is acceptable
o it should be possible to recognize security enhanced
responses
o it should be possible to assign cryptographic keys (make
use of the security services) to leaf nodes in the DNS
tree, i.e., fully qualified domain names
o it should be possible to not trust secondary servers
o a mechanism must exist for revoking cryptographic keys
that works within the DNS time-to-live framework
o security services should be supported with no additional
DNS queries beyond what would be required if security was
not supported
o it must be possible to ensure that cached data expires
according to its TTL
The meeting concluded with agreement on the following three
milestones.
1. The desired functional requirements are to be reviewed and
agreed upon by November 30.
2. Strawman proposals that meet as many of the desired
requirements as possible are due by January 31, 1994.
3. The group would produce a single, draft proposal at the
next IETF meeting, March 1994.
The DNS Security effort will be spun off as a separate working group in
the Service Applications Area (SAP), as soon as James can get the
charter approved. The DNS Security mailing list is
dns-security@tis.com; requests to subscribe should be sent to
dns-security-request@tis.com.
Discussion of the incremental zone transfer protocol
(draft-ietf-dns-ixfr-00.txt) was deferred because none of the authors
were present at the meeting. Comments on this draft should be sent to
the authors and/or the Namedroppers mailing list.
DNS Efforts to Support SIPP
Sue Thomson gave a brief report on current DNS efforts to support SIPP
(the merger of the SIP and PIP proposals). See the latest version of
the Internet-Draft, draft-ietf-sip-sippdns-nn.txt, for details.
DNS Reliability Issues - Boeing
Ed King gave a presentation on DNS reliability issues in Boeing's
production environment. Ed has to support DNS on a corporate network
with thousands of subnets and DNS software from many vendors in a
production environment that never shuts down and where an interruption
to DNS services due to a power hit can leave hundreds of engineers
sitting idle waiting for their workstations to finish booting. Much of
the problem is that each vendor has their own slightly different (and
often more than slightly broken) interface between DNS, local host
tables, and the vendor's own pet name resolution mechanism. Replacing
or repairing all the DNS software in an environment isn't economically
feasible, so the most constructive approach seems to be to write a ``DNS
Requirements'' document to use as a reference when pressuring vendors to
fix their DNS implementations. The DNS portion of the Host Requirements
documents (RFC 1123 section 6.1) and the newly published DNS ``Common
Errors'' Informational RFCs are good starting points, but companies like
Boeing need a document that has the force of a standard and that goes
into more detail on interface design issues than Host Requirements does.
No definite decision was reached as a result of Ed's presentation, but
watch Namedroppers for further discussion and probably a call to form a
working group.
DNS Support for DHC and Mobile Hosts
Masataka Ohta gave a presentation on a possible way to implement some of
the DNS support needed for dynamic host configuration and mobile hosts.
The presentation went into more detail than there is room for in these
minutes, so expect to see a summary of this on the Namedroppers list.
The Future of the DNS Working Group
Dave Crocker spoke about the future of the DNS Working Group. As has
been discussed at previous meetings, the DNS Working Group as currently
organized doesn't really fit well into the current IETF organizational
framework. Accordingly, Dave asks that DNS reorganize itself more along
the current IETF pattern. The proposal is to move the ``permanent''
functions of the DNS Working Group (DNS oversight within the IETF,
mostly) into the SAP Area Directorate, that Dave will be forming ``Real
Soon Now,'' while reincarnating specific closed-ended tasks as separate
working groups within the SAP Area. The SAP Area Directorate will hold
open meetings at regular intervals, so that there will still be a forum
for overall DNS design work. For formal purposes, the current DNS
Working Group will probably be retroactively construed as having been
the DNS MIB Working Group, and will be closed down as soon as the DNS
MIB documents hit the streets. As a practical matter, and in the
Chair's opinion, the current DNS Working Group will effectively
reconstitute itself as the attendees of the DNS portion of the SAP Area
Directorate open meetings. Dave expects to have the reorganization
completed by the 29th IETF in Seattle.
The discussion that followed Dave's statement made it clear that there
are people with strong feelings on both sides of this issue (keep the
DNS Working Group as it is versus reorganize per Dave's plan). Unless
somebody feels strongly enough about this to make a formal appeal, the
reorganization will probably go through.
Attendees
Steve Alexander stevea@lachman.com
Garrett Alexander gda@tycho.ncsc.mil
Robert Austein sra@epilogue.com
Anders Baardsgaad anders@cc.uit.no
Alireza Bahreman bahreman@bellcore.com
William Barns barns@gateway.mitre.org
Stephen Crocker crocker@tis.com
Donald Eastlake dee@skidrow.lkg.dec.com
Havard Eidnes havard.eidnes@runit.sintef.no
Erik Fair fair@apple.com
Roger Fajman raf@cu.nih.gov
Patrik Faltstrom paf@nada.kth.se
Antonio Fernandez afa@thumper.bellcore.com
James Fielding jamesf@arl.army.mil
James Galvin galvin@tis.com
Chris Gorsuch chrisg@lobby.ti.com
Ronald Jacoby rj@sgi.com
Rick Jones raj@cup.hp.com
Charlie Kaufman kaufman@zk3.dec.com
Elizabeth Kaufman kaufman@biomded.med.yale.edu
Stephen Kent kent@bbn.com
Edwin King eek@atc.boeing.com
Paul Lambert paul_lambert@email.mot.com
Walter Lazear lazear@gateway.mitre.org
Lars-Johan Liman liman@ebone.net
John Linn linn@security.ov.com
Jun Matsukata jm@eng.isas.ac.jp
Paul Mockapetris pvm@darpa.mil
Sath Nelakonda sath@lachman.com
Masataka Ohta mohta@cc.titech.ac.jp
Michael Patton map@bbn.com
Jon Postel postel@isi.edu
Jeffrey Schiller jis@mit.edu
Richard Schmalgemeier rgs@merit.edu
Michael St. Johns stjohns@arpa.mil
John Stewart jstewart@cnri.reston.va.us
Theodore Ts'o tytso@mit.edu
Walter Wimer walter.wimer@andrew.cmu.edu
David Woodgate David.Woodgate@its.csiro.au
Weiping Zhao zhao@nacsis.ac.jp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
This Internet-Draft was deleted. For more information, send a message to
Internet-Drafts@cnri.reston.va.us

1683
doc/rfc1533.txt Normal file

File diff suppressed because it is too large Load Diff

200
errwarn.c Normal file
View File

@ -0,0 +1,200 @@
/* errwarn.c
Errors and warnings... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 RadioMail Corporation. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <syslog.h>
#include <errno.h>
static void do_percentm PROTO ((char *obuf, char *ibuf));
static char mbuf [1024];
static char fbuf [1024];
/* Log an error message, then exit... */
int 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_ERR, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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_ERR, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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_INFO, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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_DEBUG, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
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;
while (*s)
{
if (infmt)
{
if (*s == 'm')
{
strcpy (p - 1, strerror (errno));
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
{
extern int tline, tlpos;
va_list list;
do_percentm (mbuf, fmt);
snprintf (fbuf, sizeof fbuf, "dhcpd.conf line %d char %d: %s",
tline, tlpos, mbuf);
VA_start (list, fmt);
vsnprintf (mbuf, sizeof mbuf, fbuf, list);
va_end (list);
#ifndef DEBUG
syslog (LOG_ERROR, mbuf);
#else
write (1, mbuf, strlen (mbuf));
write (1, "\n", 1);
#endif
return 0;
}

152
hash.c Normal file
View File

@ -0,0 +1,152 @@
/* hash.c
Routines for manipulating hash tables... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
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,
DEFAULT_HASH_SIZE * sizeof (struct hash_bucket *));
return rv;
}
static INLINE do_hash (name, len, size)
char *name;
int len;
int size;
{
register int accum = 0;
register unsigned char *s = (unsigned char *)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;
char *name;
unsigned char *pointer;
{
int hashno = do_hash (name, len, table -> hash_count);
struct hash_bucket *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];
table -> buckets [hashno] = bp;
}
void delete_hash_entry (table, name, len)
struct hash_table *table;
int len;
char *name;
{
int hashno = do_hash (name, len, table -> hash_count);
struct hash_bucket *bp, *pbp = (struct hash_bucket *)0;
/* 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 (bp -> name, 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;
}
}
}
unsigned char *hash_lookup (table, name, len)
struct hash_table *table;
char *name;
int len;
{
int hashno = do_hash (name, len, table -> hash_count);
struct hash_bucket *bp;
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 (bp -> name, name))
return bp -> value;
}
return (unsigned char *)0;
}

55
hash.h Normal file
View File

@ -0,0 +1,55 @@
/* hash.h
Definitions for hashing... */
/*
* 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''.
*/
#define DEFAULT_HASH_SIZE 97
struct hash_bucket {
struct hash_bucket *next;
char *name;
int len;
unsigned char *value;
};
struct hash_table {
int hash_count;
struct hash_bucket *buckets [DEFAULT_HASH_SIZE];
};

49
includes/cdefs.h Normal file
View File

@ -0,0 +1,49 @@
/* cdefs.h
Standard C definitions... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#if defined (__GNUC__) || defined (__STDC__)
#define PROTO(x) x
#define KandR(x)
#define ANSI_DECL(x) x
#define INLINE inline
#else
#define PROTO(x) ()
#define KandR(x) x
#define ANSI_DECL(x)
#define INLINE
#endif

106
includes/cf/bsdos.h Normal file
View File

@ -0,0 +1,106 @@
/* bsdos.h
System dependencies for BSD/os... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#include <sys/types.h>
#include <string.h>
#include <paths.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <setjmp.h>
#include <limits.h>
#include <netdb.h>
extern int h_errno;
#include <net/if.h>
/* Time stuff... */
#include <sys/time.h>
#define TIME struct timeval
#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
#define TIME_DIFF_US(high, low) \
(((high) -> tv_sec - (low) -> tv_sec) * 1000000 \
+ ((high) -> tv_usec - (low) -> tv_usec))
#define SET_TIME(x, y) (((x) -> tv_sec = ((y) / 1000000)), \
((x) -> tv_usec = ((y) % 1000000)))
#define DELAY() usleep (2000)
#define DELAY_ONE_SECOND() usleep (1000000)
/* Login stuff... */
#include <utmp.h>
#include <sys/syslimits.h>
#define _PATH_LOGIN "/usr/bin/login"
#define SETLOGIN(x) setlogin (x)
#define SETUID(x) setuid (x)
#define SETGID(x) (setgroups (0, &x), setgid (x))
#define USER_MAX UT_NAMESIZE
/* Varargs stuff... */
#include <stdarg.h>
#define VA_DOTDOTDOT ...
#define va_dcl
#define VA_start(list, last) va_start (list, last)
#define _PATH_MPOOL_PID "/var/run/mpoold.pid"
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#include <sys/time.h>
#define TIME struct timeval
#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
#define TIME_DIFF(high, low) \
(((high) -> tv_sec == (low) -> tv_sec) \
? ((high) -> tv_usec > (low) -> tv_usec \
? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
: (high) -> tv_sec - (low) -> tv_sec)
#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
#define ADD_TIME(d, s1, s2) { \
(d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
(d) -> tv_sec = (d) -> tv_usec / 1000000; \
(d) -> tv_usec %= 1000000; \
} else \
(d) -> tv_sec = 0; \
(d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
}
#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
((x) -> tv_usec = 999999))

73
includes/cf/netbsd.h Normal file
View File

@ -0,0 +1,73 @@
/* netbsd.h
System dependencies for NetBSD... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#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>
#include <netdb.h>
extern int h_errno;
#include <net/if.h>
/* Varargs stuff... */
#include <stdarg.h>
#define VA_DOTDOTDOT ...
#define va_dcl
#define VA_start(list, last) va_start (list, last)
#define _PATH_DHCPD_PID "/var/run/dhcpd.pid"
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#include <sys/time.h>
#define TIME time_t
#define GET_TIME(x) time ((x))
#define TIME_DIFF(high, low) (*(high) - *(low))
#define SET_TIME(x, y) (*(x) = (y))
#define ADD_TIME(d, s1, s2) (*(d) = *(s1) + *(s2))
#define SET_MAX_TIME(x) (*(x) = INT_MAX)

83
includes/cf/sunos4.h Normal file
View File

@ -0,0 +1,83 @@
/* sunos4.h
System dependencies for SunOS 4 (tested on 4.1.4)... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <setjmp.h>
#include <limits.h>
#include <netdb.h>
extern int h_errno;
#include <net/if.h>
/* Varargs stuff... */
#include <varargs.h>
#define VA_DOTDOTDOT va_alist
#define VA_start(list, last) va_start (list)
#define vsnprintf(buf, size, fmt, list) vsprintf (buf, fmt, list)
#define EOL '\n'
#define VOIDPTR void *
/* Time stuff... */
#include <sys/time.h>
#define TIME struct timeval
#define GET_TIME(x) gettimeofday ((x), (struct timezone *)0)
#define TIME_DIFF(high, low) \
(((high) -> tv_sec == (low) -> tv_sec) \
? ((high) -> tv_usec > (low) -> tv_usec \
? 1 : (((high) -> tv_usec == (low) -> tv_usec) ? 0 : -1)) \
: (high) -> tv_sec - (low) -> tv_sec)
#define SET_TIME(x, y) (((x) -> tv_sec = ((y))), ((x) -> tv_usec = 0))
#define ADD_TIME(d, s1, s2) { \
(d) -> tv_usec = (s1) -> tv_usec + (s2) -> tv_usec; \
if ((d) -> tv_usec > 1000000 || (d) -> tv_usec < -1000000) { \
(d) -> tv_sec = (d) -> tv_usec / 1000000; \
(d) -> tv_usec %= 1000000; \
} else \
(d) -> tv_sec = 0; \
(d) -> tv_sec += (s1) -> tv_sec + (s2) -> tv_sec; \
}
#define SET_MAX_TIME(x) (((x) -> tv_sec = INT_MAX), \
((x) -> tv_usec = 999999))

155
includes/dhcp.h Normal file
View File

@ -0,0 +1,155 @@
/* dhcp.h
Protocol structures... */
/*
* 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''.
*/
#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_LEN (236 + DHCP_UDP_OVERHEAD) /* Everything but
options. */
#define DHCP_MTU_MAX 1500
#define DHCP_OPTION_LEN (DHCP_MTU_MAX - DHCP_FIXED_LEN)
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 */
char chaddr [16]; /* Client hardware address */
char sname [64]; /* Server name */
char file [128]; /* Boot filename */
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
/* 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_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

263
includes/dhcpd.h Normal file
View File

@ -0,0 +1,263 @@
/* dhcpd.h
Definitions for dhcpd... */
/*
* 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''.
*/
#include <sys/types.h>
#include <syslog.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <stdio.h>
#include "dhcp.h"
#include "cdefs.h"
#include "osdep.h"
#include "tree.h"
#include "hash.h"
/* 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;
struct sockaddr_in client;
int client_len;
int client_sock;
struct {
int len;
unsigned char *data;
} options [256];
};
struct hardware {
u_int8_t htype;
u_int8_t hlen;
u_int8_t haddr [16];
};
/* A dhcp host declaration structure. */
struct host_decl {
struct host_decl *n_name, *n_haddr, *n_cid;
char *name;
struct hardware *interfaces;
int interface_count;
char *filename;
char *server_name;
struct tree_cache *fixed_addr;
struct tree_cache *options [256];
};
/* A dhcp lease declaration structure. */
struct lease {
struct lease *next;
struct lease *prev;
struct in_addr ip_addr;
TIME starts, ends, timestamp;
unsigned char *uid;
int uid_len;
struct host_decl *host;
struct subnet *contain;
struct hardware hardware_addr;
int state;
};
struct subnet {
struct in_addr net;
struct in_addr netmask;
struct lease *leases;
struct lease *insertion_point;
};
/* 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. */
#ifndef _PATH_DHCPD_CONF
#ifdef DEBUG
#define _PATH_DHCPD_CONF "dhcpd.conf"
#else
#define _PATH_DHCPD_CONF "/etc/dhcpd.conf"
#endif
#endif
/* Subnet macros... */
#define SUBNET(addr, mask) ((addr).s_addr & (netmask).s_addr)
#define IP_ADDR(net, host) ((net).s_addr | i)
#define HOST_ADDR(addr, mask) ((addr).s_addr & ~(netmask).s_addr)
#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));
void cons_options PROTO ((struct packet *, struct dhcp_packet *,
struct host_decl *, int));
char *pretty_print_option PROTO ((unsigned char, unsigned char *, int));
/* errwarn.c */
int error PROTO ((char *, ...));
int warn PROTO ((char *, ...));
int note PROTO ((char *, ...));
int debug PROTO ((char *, ...));
int parse_warn PROTO ((char *, ...));
/* dhcpd.c */
TIME cur_time;
extern u_int32_t *server_addrlist;
extern int server_addrcount;
extern u_int16_t server_port;
int main PROTO ((int, char **, char **));
void cleanup PROTO ((void));
void do_packet PROTO ((unsigned char *, int, struct sockaddr_in *, int, int));
u_int32_t pick_interface PROTO ((struct packet *));
/* conflex.c */
int next_token PROTO ((char **, FILE *));
int peek_token PROTO ((char **, FILE *));
/* confpars.c */
void readconf PROTO ((void));
void parse_statement PROTO ((FILE *));
void skip_to_semi PROTO ((FILE *));
struct host_decl *parse_host_statement PROTO ((FILE *, jmp_buf *));
char *parse_host_name PROTO ((FILE *, jmp_buf *));
void parse_host_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
void parse_hardware_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
struct hardware parse_hardware_addr PROTO ((FILE *, jmp_buf *));
void parse_filename_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
void parse_fixed_addr_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
void parse_option_decl PROTO ((FILE *, jmp_buf *, struct host_decl *));
TIME parse_timestamp PROTO ((FILE *, jmp_buf *));
TIME parse_date PROTO ((FILE *, jmp_buf *));
struct lease *parse_lease_statement PROTO ((FILE *, jmp_buf *));
void parse_address_range PROTO ((FILE *, jmp_buf *));
unsigned char *parse_numeric_aggregate PROTO ((FILE *, jmp_buf *,
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 */
void dhcp PROTO ((struct packet *));
/* bootp.c */
void bootp PROTO ((struct packet *));
/* memory.c */
void enter_host PROTO ((struct host_decl *));
struct host_decl *find_host_by_name PROTO ((char *name));
struct host_decl *find_host_by_addr PROTO ((int, unsigned char *, int));
extern struct subnet *find_subnet (struct in_addr);
void enter_subnet (struct subnet *);
void enter_lease PROTO ((struct lease *));
void supersede_lease PROTO ((struct lease *, struct lease *));
struct lease *find_lease_by_uid PROTO ((unsigned char *, int));
struct lease *find_lease_by_ip_addr PROTO ((struct in_addr));
struct lease *find_next_expiring_lease 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 (int, char *);
struct subnet *new_subnet PROTO ((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 *));
/* socket.c */
u_int32_t *get_interface_list PROTO ((int *));
void listen_on PROTO ((u_int16_t, u_int32_t));
void dispatch PROTO ((void));
/* hash.c */
struct hash_table *new_hash PROTO ((void));
void add_hash PROTO ((struct hash_table *, char *, int, unsigned char *));
void delete_hash_entry PROTO ((struct hash_table *, char *, int));
unsigned char *hash_lookup PROTO ((struct hash_table *, 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 struct hash_table universe_hash;
extern struct universe dhcp_universe;
void initialize_universes PROTO ((void));

71
includes/dhctoken.h Normal file
View File

@ -0,0 +1,71 @@
/* dhctoken.h
Tokens for config file lexer and parser. */
/*
* 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''.
*/
#define SEMI ';'
#define DOT '.'
#define COLON ':'
#define COMMA ','
#define SLASH '/'
#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_ATOM 264
#define ATOM 265
#define TIMESTAMP 266
#define STARTS 267
#define ENDS 268
#define UID 269
#define CLASS 270
#define LEASE 271
#define RANGE 272
#define LAST_TOKEN RANGE
#define is_identifier(x) ((x) >= FIRST_TOKEN && \
(x) <= FIRST_TOKEN && \
(x) != STRING && \
(x) != NUMBER)

55
includes/hash.h Normal file
View File

@ -0,0 +1,55 @@
/* hash.h
Definitions for hashing... */
/*
* 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''.
*/
#define DEFAULT_HASH_SIZE 97
struct hash_bucket {
struct hash_bucket *next;
char *name;
int len;
unsigned char *value;
};
struct hash_table {
int hash_count;
struct hash_bucket *buckets [DEFAULT_HASH_SIZE];
};

50
includes/osdep.h Normal file
View File

@ -0,0 +1,50 @@
/* osdep.h
Operating system dependencies... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#ifdef sun
#include "cf/sunos4.h"
#endif
#ifdef bsdi
#include "cf/bsdos.h"
#endif
#ifdef __NetBSD__
#include "cf/netbsd.h"
#endif

104
includes/tree.h Normal file
View File

@ -0,0 +1,104 @@
/* 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;
};
struct universe {
char *name;
struct hash_table *hash;
struct option *options [256];
};
struct option {
char *name;
char *format;
struct universe *universe;
unsigned char code;
};

395
memory.c Normal file
View File

@ -0,0 +1,395 @@
/* memory.c
Memory-resident database... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static struct host_decl *hosts;
static struct hash_table *subnet_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;
void enter_host (hd)
struct host_decl *hd;
{
hd -> n_name = hosts;
hd -> n_haddr = hosts;
hd -> n_cid = hosts;
hosts = hd;
}
struct host_decl *find_host_by_name (name)
char *name;
{
struct host_decl *foo;
for (foo = hosts; foo; foo = foo -> n_name)
if (!strcmp (name, foo -> name))
return foo;
return (struct host_decl *)0;
}
struct host_decl *find_host_by_addr (htype, haddr, hlen)
int htype;
unsigned char *haddr;
int hlen;
{
struct host_decl *foo;
int i;
for (foo = hosts; foo; foo = foo -> n_haddr)
for (i = 0; i < foo -> interface_count; i++)
if (foo -> interfaces [i].htype == htype &&
foo -> interfaces [i].hlen == hlen &&
!memcmp (foo -> interfaces [i].haddr, haddr, hlen))
return foo;
return (struct host_decl *)0;
}
void new_address_range (low, high, netmask)
struct in_addr low, high, netmask;
{
struct lease *address_range, *lp, *plp;
struct subnet *subnet;
struct in_addr net;
int i, max;
char lowbuf [16], highbuf [16], netbuf [16];
/* Initialize the hash table if it hasn't been done yet. */
if (!subnet_hash)
subnet_hash = new_hash ();
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.s_addr = SUBNET (low, netmask);
if (net.s_addr != SUBNET (high, netmask)) {
strcpy (lowbuf, inet_ntoa (low));
strcpy (highbuf, inet_ntoa (high));
strcpy (netbuf, inet_ntoa (netmask));
error ("Address range %s to %s, netmask %s spans %s!",
lowbuf, highbuf, netbuf, "multiple subnets");
}
/* See if this subnet is already known - if not, make a new one. */
subnet = find_subnet (net);
if (!subnet) {
subnet = new_subnet ("new_address_range");
if (!subnet)
error ("No memory for new subnet");
subnet -> net = net;
subnet -> netmask = netmask;
subnet -> leases = (struct lease *)0;
enter_subnet (subnet);
}
/* Get the high and low host addresses... */
max = HOST_ADDR (high, netmask);
i = HOST_ADDR (low, netmask);
/* Allow range to be specified high-to-low as well as low-to-high. */
if (i > max) {
max = i;
i = HOST_ADDR (high, netmask);
}
/* Get a lease structure for each address in the range. */
address_range = new_leases (max - i + 1, "new_address_range");
if (!address_range) {
strcpy (lowbuf, inet_ntoa (low));
strcpy (highbuf, inet_ntoa (high));
error ("No memory for address range %s-%s.", lowbuf, highbuf);
}
memset (address_range, 0, (sizeof *address_range) * (max - i + 1));
/* Fill out the lease structures with some minimal information. */
for (; i <= max; i++) {
address_range [i].ip_addr.s_addr = IP_ADDR (subnet -> net, i);
address_range [i].starts =
address_range [i].timestamp = MIN_TIME;
address_range [i].ends = MIN_TIME;
address_range [i].contain = subnet;
/* Link this entry into the list. */
address_range [i].next = subnet -> leases;
address_range [i].prev = (struct lease *)0;
subnet -> leases = &address_range [i];
address_range [i].next -> prev = subnet -> leases;
add_hash (lease_ip_addr_hash,
(char *)&address_range [i].ip_addr,
sizeof address_range [i].ip_addr,
(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 in_addr lnet;
int lhost;
lnet.s_addr = SUBNET (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 (lnet.s_addr == subnet -> net.s_addr &&
lhost >= i && lhost <= max) {
if (plp) {
plp -> next = lp -> next;
} else {
dangling_leases = lp -> next;
}
lp -> next = (struct lease *)0;
supersede_lease (&address_range [lhost - i], lp);
free_lease (lp, "new_address_range");
} else
plp = lp;
}
}
struct subnet *find_subnet (subnet)
struct in_addr subnet;
{
struct subnet *rv;
return (struct subnet *)hash_lookup (subnet_hash,
(char *)&subnet, sizeof subnet);
}
/* Enter a new subnet into the subnet hash. */
void enter_subnet (subnet)
struct subnet *subnet;
{
add_hash (subnet_hash, (char *)&subnet -> net,
sizeof subnet -> net, (unsigned char *)subnet);
}
/* 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",
inet_ntoa (lease -> ip_addr));
}
*comp = *lease;
lease -> next = dangling_leases;
lease -> prev = (struct lease *)0;
dangling_leases = lease;
} else {
supersede_lease (comp, lease);
}
}
/* 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. */
void supersede_lease (comp, lease)
struct lease *comp, *lease;
{
int enter_uid = 0;
int enter_hwaddr = 0;
struct subnet *parent;
struct lease *lp;
/* 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 (comp -> ends > cur_time &&
((comp -> 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",
inet_ntoa (comp -> ip_addr));
} else {
/* If there's a Unique ID, dissociate it from the hash
table if necessary, and always free it. */
if (comp -> uid) {
if (comp -> uid_len != lease -> uid_len ||
memcmp (comp -> uid, lease -> uid,
comp -> uid_len)) {
delete_hash_entry (lease_uid_hash,
comp -> uid,
comp -> uid_len);
enter_uid = 1;
}
free (comp -> uid);
}
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)) {
delete_hash_entry (lease_hw_addr_hash,
comp -> hardware_addr.haddr,
comp -> hardware_addr.hlen);
enter_hwaddr = 1;
}
/* Copy the data files, but not the linkages. */
comp -> starts = lease -> starts;
comp -> ends = lease -> ends;
comp -> timestamp = lease -> timestamp;
comp -> uid = lease -> uid;
comp -> uid_len = lease -> uid_len;
comp -> host = lease -> host;
comp -> hardware_addr = lease -> hardware_addr;
comp -> state = lease -> state;
/* Record the lease in the uid hash if necessary. */
if (enter_uid && lease -> uid) {
add_hash (lease_uid_hash, lease -> uid,
lease -> uid_len, (unsigned char *)lease);
}
/* Record it in the hardware address hash if necessary. */
if (enter_hwaddr && lease -> hardware_addr.htype) {
add_hash (lease_hw_addr_hash,
lease -> hardware_addr.haddr,
lease -> hardware_addr.hlen,
(unsigned char *)lease);
}
/* Remove the lease from its current place in the list. */
if (comp -> prev) {
comp -> prev -> next = comp -> next;
} else {
comp -> contain -> leases = comp -> next;
}
if (comp -> next) {
comp -> next -> prev = comp -> prev;
}
/* Find the last insertion point... */
if (comp == comp -> contain -> insertion_point ||
!comp -> contain -> insertion_point) {
lp = comp -> contain -> leases;
} else {
lp = comp -> contain -> insertion_point;
}
if (!lp) {
/* Nothing on the list yet? Just make comp the
head of the list. */
comp -> contain -> leases = comp;
} else if (lp -> ends <= comp -> ends) {
/* Skip down the list until we run out of list
or find a place for comp. */
while (lp -> next && lp -> ends < comp -> ends) {
lp = lp -> next;
}
if (lp -> ends < comp -> ends) {
/* If we ran out of list, put comp
at the end. */
lp -> next = comp;
comp -> prev = lp;
comp -> next = (struct lease *)0;
} else {
/* If we didn't, put it between lp and
the previous item on the list. */
comp -> prev = lp -> prev;
comp -> prev -> next = comp;
comp -> next = lp;
lp -> prev = comp;
}
} else {
/* Skip ip the list until we run out of list
or find a place for comp. */
while (lp -> prev && lp -> ends > comp -> ends) {
lp = lp -> prev;
}
if (lp -> ends > comp -> ends) {
/* If we ran out of list, put comp
at the beginning. */
lp -> prev = comp;
comp -> next = lp;
comp -> prev = (struct lease *)0;
comp -> contain -> leases = comp;
} else {
/* If we didn't, put it between lp and
the next item on the list. */
comp -> next = lp -> next;
comp -> next -> prev = comp;
comp -> prev = lp;
lp -> next = comp;
}
}
comp -> contain -> insertion_point = comp;
}
}

556
options.c Normal file
View File

@ -0,0 +1,556 @@
/* options.c
DHCP options parsing and reassembly. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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_LEN);
/* 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,
packet -> raw -> file,
sizeof packet -> raw -> file);
if (packet -> options [DHO_DHCP_OPTION_OVERLOAD].data [0] & 2)
parse_option_buffer (packet,
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);
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 up options based on client-supplied desired option list (if any)
and selected server option list. */
void cons_options (inpacket, outpacket, hp, overload)
struct packet *inpacket;
struct dhcp_packet *outpacket;
struct host_decl *hp;
int overload; /* Overload flags that may be set. */
{
option_mask options_have; /* Options we can send. */
option_mask options_want; /* Options client wants. */
option_mask options_done; /* Options we've already encoded. */
option_mask temp; /* Working option mask. */
unsigned char *priority_list;
int priority_len;
unsigned char *buffer = inpacket -> raw -> options;
int buflen, bufix;
int reserved = 3; /* Reserved space for overload. */
unsigned char *overload_ptr = (unsigned char *)0;
int stored_length [256];
int missed = 0;
int missed_code;
int missed_length;
int result;
int i;
/* If there's no place to overload with options, don't save space
for an overload option. */
if (!overload)
reserved = 0;
/* Zero out the stored-lengths array. */
memset (stored_length, 0, sizeof stored_length);
/* If the client has provided a maximum DHCP message size,
use that. Otherwise, we use the default MTU size (576 bytes). */
/* XXX Maybe it would be safe to assume that we can send a packet
to the client that's as big as the one it sent us, even if it
didn't specify a large MTU. */
if (inpacket -> options [DHO_DHCP_MAX_MESSAGE_SIZE].data)
buflen = (getUShort (inpacket -> options
[DHO_DHCP_MAX_MESSAGE_SIZE].data)
- DHCP_FIXED_LEN);
else
buflen = 576 - DHCP_FIXED_LEN;
/* If the client has provided a list of options that it wishes
returned, use it to prioritize. */
if (inpacket -> options [DHO_DHCP_PARAMETER_REQUEST_LIST].data) {
priority_list =
inpacket -> options
[DHO_DHCP_PARAMETER_REQUEST_LIST].data;
priority_len =
inpacket -> options
[DHO_DHCP_PARAMETER_REQUEST_LIST].len;
} else {
/* Otherwise, prioritize based on the default priority list. */
priority_list = dhcp_option_default_priority_list;
priority_len = sizeof_dhcp_option_default_priority_list;
}
/* Make a bitmask of all the options the client wants. */
OPTION_ZERO (options_want);
for (i = 0; i < priority_len; i++)
OPTION_SET (options_want, priority_list [i]);
/* Make a bitmask of all the options we have available. */
OPTION_ZERO (options_have);
for (i = 0; i < 256; i++)
if (hp -> options [i])
OPTION_SET (options_have, i);
again:
/* Try copying out options that fit easily. */
for (i = 0; i < priority_len; i++) {
/* Code for next option to try to store. */
int code = priority_list [i];
/* 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 (!hp -> options [code])
continue;
/* Don't look at options that have already been stored. */
if (OPTION_ISSET (options_done, code))
continue;
/* Find the value of the option... */
if (!tree_evaluate (hp -> options [code]))
continue;
/* We should now have a constant length for the option. */
length = (hp -> options [code] -> len - stored_length [code]);
/* If there's no space for this option, skip it. */
if ((bufix + OPTION_SPACE (length) + reserved) > buflen) {
/* If this is the first missed option, remember it. */
if (++missed == 1) {
missed_code = code;
missed_length = length;
}
continue;
}
/* Otherwise, store the option. */
result = store_option (outpacket, code,
buffer + bufix,
buflen - bufix - reserved,
stored_length);
bufix += result;
/* The following test should always succeed because of
preconditioning above. */
if (stored_length [code] == hp -> options [code] -> len)
OPTION_SET (options_done, code);
else {
warn ("%s: Only stored %d out of %d bytes.",
dhcp_options [code].name,
stored_length [code],
hp -> options [code] -> len);
if (++missed == 1) {
missed_code = code;
missed_length = hp -> options [code] -> len
- stored_length [code];
}
}
}
/* If we didn't miss any options, we're done. */
/* XXX Maybe we want to try to encode options the client didn't
request but that we have available? */
if (!missed)
return;
/* If we did miss one or more options, they must not have fit.
It's possible, though, that there's only one option left to
store, and that it would fit if we weren't reserving space
for the overload option. In that case, we want to avoid
overloading. */
if (reserved && missed == 1
&& (bufix + OPTION_SPACE (missed_length) <= buflen)) {
result = store_option (outpacket, missed_code,
buffer + bufix, buflen - bufix,
stored_length);
bufix += result;
/* This test should always fail -- we'll send bad
data if it doesn't. */
if (stored_length [missed_code]
== hp -> options [missed_code] -> len) {
OPTION_SET (options_done, missed_code);
} else {
warn ("%s (last): Only stored %d out of %d bytes.",
dhcp_options [missed_code].name,
stored_length [missed_code],
hp -> options [missed_code] -> len);
}
return;
}
/* We've crammed in all the options that completely fit in
the current buffer, but maybe we can fit part of the next
option into the current buffer and part into the next. */
if (bufix + OPTION_SPACE (missed_length) + reserved
< buflen + (overload & 1 ? 128 : 0) + (overload & 2 ? 64 : 0)) {
result = store_option (outpacket, missed_code,
buffer + bufix,
buflen - bufix - reserved,
stored_length);
bufix += result;
/* This test should never fail. */
if (stored_length [missed_code]
== hp -> options [missed_code] -> len) {
OPTION_SET (options_done, missed_code);
warn ("%s: Unexpected completed store.",
dhcp_options [missed_code].name);
}
}
/* Okay, nothing else is going to fit in the current buffer
except possibly the override option. Store that. */
if (reserved) {
buffer [bufix++] = DHO_DHCP_OPTION_OVERLOAD;
buffer [bufix++] = 1;
overload_ptr = buffer + bufix;
buffer [bufix++] = 0;
/* If there's space, store an End option code. */
if (bufix < buflen)
buffer [bufix++] = DHO_END;
/* If there's still space, pad it. */
while (bufix < buflen)
buffer [bufix++] = DHO_PAD;
}
/* If we've fallen through to here, we still have options to
store, and may be able to overload options into the file
and server name fields of the DHCP packet. */
/* We should have stored an overload option by now if we're
going to need it, so if this test fails, there's a programming
error somewhere above. */
if (overload && !overload_ptr) {
warn ("Need to overload, but didn't store overload option!");
return;
}
/* Can we use the file buffer? */
if (overload & 1) {
buffer = inpacket -> raw -> file;
buflen = sizeof inpacket -> raw -> file;
bufix = 0;
overload &= ~1;
goto again;
}
/* Can we use the sname buffer? */
if (overload & 2) {
buffer = inpacket -> raw -> sname;
buflen = sizeof inpacket -> raw -> sname;
bufix = 0;
overload &= ~2;
goto again;
}
warn ("Insufficient packet space for all options.");
}
/* Copy the option data specified by code from the packet structure's
option array into an option buffer specified by buf and buflen,
updating stored_length[code] to reflect the amount of code's option
data that has been stored so far. Return 1 if all the option data
has been stored. */
int store_option (packet, code, buffer, buflen, stored_length)
struct packet *packet;
unsigned char code;
unsigned char *buffer;
int buflen;
int *stored_length;
{
int length = packet -> options [code].len - stored_length [code];
int bufix = 0;
int rv = 1;
if (length > buflen) {
rv = 0;
length = buflen;
}
/* If the option's length is more than 255, we must store it
in multiple hunks. Store 255-byte hunks first. */
/* XXX Might a client lose its cookies if options aren't
chunked out so that each chunk is aligned to the size
of the data being represented? */
while (length) {
unsigned char incr = length > 255 ? 255 : length;
buffer [bufix] = code;
buffer [bufix + 1] = incr;
memcpy (buffer + bufix + 2, (packet -> options [code].data
+ stored_length [code]), incr);
length -= incr;
stored_length [code] += incr;
bufix += 2 + incr;
}
return rv;
}
/* Format the specified option so that a human can easily read it. */
char *pretty_print_option (code, data, len)
unsigned char code;
unsigned char *data;
int len;
{
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;
/* 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 '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;
printf ("numhunk = %d numelem = %d\n", numhunk, numelem);
/* 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':
strcpy (op, dp);
break;
case 'I':
foo.s_addr = htonl (getULong (dp));
strcpy (op, inet_ntoa (foo));
dp += 4;
break;
case 'l':
sprintf (op, "%ld", getLong (dp));
dp += 4;
break;
case 'L':
sprintf (op, "%ld", 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 'f':
strcpy (op, *dp++ ? "true" : "false");
break;
default:
warn ("Unexpected format code %c", fmtbuf [j]);
}
op += strlen (op);
*op++ = ' ';
}
}
*--op = 0;
return optbuf;
}

50
osdep.h Normal file
View File

@ -0,0 +1,50 @@
/* osdep.h
Operating system dependencies... */
/*
* 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 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 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, and is based on an earlier
* design by Paul Vixie.
*/
#ifdef sun
#include "cf/sunos4.h"
#endif
#ifdef bsdi
#include "cf/bsdos.h"
#endif
#ifdef __NetBSD__
#include "cf/netbsd.h"
#endif

65
print.c Normal file
View File

@ -0,0 +1,65 @@
/* print.c
Turn data structures into printable text. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
char *print_hw_addr (htype, hlen, data)
int htype;
int hlen;
unsigned char *data;
{
static char habuf [49];
char *s;
int i;
s = habuf;
for (i = 0; i < hlen; i++) {
sprintf (s, "%x", data [i]);
s += strlen (s);
*s++ = ':';
}
*--s = 0;
return habuf;
}

147
server/bootp.c Normal file
View File

@ -0,0 +1,147 @@
/* bootp.c
BOOTP Protocol support. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
void bootp (packet)
struct packet *packet;
{
int result;
struct host_decl *hp = find_host_by_addr (packet -> raw -> htype,
packet -> raw -> chaddr,
packet -> raw -> hlen);
struct dhcp_packet *reply;
struct sockaddr_in to;
/* If the packet is from a host we don't know, drop it on
the floor. XXX */
if (!hp) {
note ("Can't find record for BOOTP host %s",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr));
return;
}
/* If we don't have a fixed address for it, drop it on the floor.
XXX */
if (!hp -> fixed_addr || !tree_evaluate (hp -> fixed_addr)) {
note ("No fixed address for BOOTP host %s (%s)",
print_hw_addr (packet -> raw -> htype,
packet -> raw -> hlen,
packet -> raw -> chaddr),
hp -> name);
return;
}
reply = new_dhcp_packet ("bootp");
if (!reply) {
free_dhcp_packet (packet -> raw, "bootp");
free_packet (packet, "bootp");
return;
}
/* Take the fields that we care about... */
reply -> op = BOOTREPLY;
reply -> htype = packet -> raw -> htype;
reply -> hlen = packet -> raw -> hlen;
memcpy (reply -> chaddr, packet -> raw -> chaddr, reply -> hlen);
memset (&reply -> chaddr [reply -> hlen], 0,
(sizeof reply -> chaddr) - reply -> hlen);
reply -> hops = packet -> raw -> hops;
reply -> xid = packet -> raw -> xid;
reply -> secs = packet -> raw -> secs;
reply -> flags = 0;
reply -> ciaddr = packet -> raw -> ciaddr;
if (!tree_evaluate (hp -> fixed_addr))
warn ("tree_evaluate failed.");
debug ("fixed_addr: %x %d %d %d %d %x",
*(int *)(hp -> fixed_addr -> value), hp -> fixed_addr -> len,
hp -> fixed_addr -> buf_size, hp -> fixed_addr -> timeout,
hp -> fixed_addr -> tree);
memcpy (&reply -> yiaddr, hp -> fixed_addr -> value,
sizeof reply -> yiaddr);
reply -> siaddr.s_addr = pick_interface (packet);
reply -> giaddr = packet -> raw -> giaddr;
if (hp -> server_name) {
strncpy (reply -> sname, hp -> server_name,
(sizeof reply -> sname) - 1);
reply -> sname [(sizeof reply -> sname) - 1] = 0;
}
if (hp -> filename) {
strncpy (reply -> file, hp -> filename,
(sizeof reply -> file) - 1);
reply -> file [(sizeof reply -> file) - 1] = 0;
}
reply -> options [0] = 0;
/* XXX gateways? */
to.sin_port = server_port;
#if 0
if (packet -> raw -> flags & BOOTP_BROADCAST)
#endif
to.sin_addr.s_addr = INADDR_BROADCAST;
#if 0
else
to.sin_addr.s_addr = INADDR_ANY;
#endif
memset (reply -> options, 0, sizeof (reply -> options));
/* If we got the magic cookie, send it back. */
if (packet -> options_valid)
memcpy (reply -> options, packet -> raw -> options, 4);
to.sin_port = packet -> client.sin_port;
to.sin_family = AF_INET;
to.sin_len = sizeof to;
memset (to.sin_zero, 0, sizeof to.sin_zero);
note ("Sending bootp reply to %s, port %d",
inet_ntoa (to.sin_addr), htons (to.sin_port));
errno = 0;
result = sendto (packet -> client_sock, reply,
((char *)(&reply -> options) - (char *)reply) + 64,
0, (struct sockaddr *)&to, sizeof to);
if (result < 0)
warn ("sendto: %m");
}

1048
server/confpars.c Normal file

File diff suppressed because it is too large Load Diff

142
server/db.c Normal file
View File

@ -0,0 +1,142 @@
/* db.c
IP Address Allocation database... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
/*
The IP Address Allocation Database tracks addresses that have been
allocated from the free pool as specified in dhcpd.conf. The
database is maintained in two parts to maintain integrity: the
journal file and the data file.
Both files are free-form flat files similar to dhcpd.conf, but with
a more limited syntax - all that can be specified are leases and
who they belong to.
When dhcpd starts up, it reads the entire data file into memory.
It then reads the journal file into memory and makes corrections to
the data based on journal entries.
While dhcpd is running, it periodically records the current time,
forks (if possible) and dumps the recorded time and its internal
database of temporarily assigned addresses into a temporary file.
It then removes any existing backup file, renames the existing file
with the backup filename, and then renames the new temporary file
with the real data file name. The link syscall is not present on
most systems, so a synchronous ``rename'' that guarantees that
exactly one file will be the master database may not be possible.
Therefore the recovery routine needs to know what to do if it finds
a backup and a temporary file, but no database file.
Whenever a client requests that an address be allocated to it, or
requests a lease renewal, and the server is able to satisfy the
request, it writes a record into the journal file indicating what
has been requested and waits for that information to reach the
disk. Once the file's dirty buffers have been flushed, the server
responds to the request, and logs another record in the journal
indicating that it has done so.
Entries in the journal file are logged along with the time at which
the logging occurred. When the server forks to dump the database,
it records the current time before forking. The copy of the server
that writes out the database records the time read prior to forking
in the new data file. The copy of the server that continues to
serve DHCP requests ensures that any journal entries subsequent to
the fork have time stamps that are greater than the time read
before forking. When recovering from a crash, the server discards
any entries in the journal which have time stamps earlier than the
time stamp on the data file.
When recovering from a crash, dhcpd may find a journal entry for a
request, but no entry indicating that it was satisfied. There is
no automatic way to recover from this, since the server may have
sent out a response, so in this case the server must notify
sysadmin of the problem and leave it to them to solve it.
In addition to the actual data files, we also keep a running log of
``interesting'' events, which we mail to the dhcp-admin alias every
morning at 7:00 AM. This log can be tailed by paranoid sysadmins
or in times of network trouble. */
/* Initialize the internal database, perform crash recovery as needed. */
void dbinit ()
{
FILE *dbfile;
/* We are assuming that on entry, there is no other dhcpd
running on this machine. If there were, there would be the
potential for serious database corruption. The main code
currently assures that there is only one server running by
listening on the bootps port with INADDR_ANY. Unices that
I'm familiar with will only allow one process to do this,
even if the SO_REUSEADDR option is set. 'twouldn't surprise
me terribly, though, if this didn't work for some other
operating system. Beware. XXX */
/* Look for a file under the official database name.
Failing that, look for a file under the backup name.
If we find neither, we assume that the database is empty. */
if ((dbfile = fopen (_PATH_DHCP_DB, "r")) != NULL
(dbfile = fopen (_PATH_DHCP_DB_BACKUP, "r") != NULL)) {
/* Read in the data file, making a list of assigned
addresses that have been removed from dhcpd.conf. */
}
/* Open the journal file and read through any entries which
are out of date. */
/* Now read entries that postdate the last database sync,
keeping track of incomplete entries (when we're done, there
should never be more than one such entry. */
/* Now expire any leases that have lapsed since we last ran. */
/* ...and we're done... */
}

52
server/dhcp.c Normal file
View File

@ -0,0 +1,52 @@
/* dhcp.c
DHCP Protocol support. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
void dhcp (packet)
struct packet *packet;
{
}

256
server/dhcpd.c Normal file
View File

@ -0,0 +1,256 @@
/* dhcpd.c
DHCP Server Daemon. */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
static void usage PROTO ((void));
TIME cur_time;
u_int32_t *server_addrlist;
int server_addrcount;
u_int16_t server_port;
int main (argc, argv, envp)
int argc;
char **argv, **envp;
{
struct in_addr addr;
int port = 0;
int i;
struct sockaddr_in name;
u_int32_t *addrlist = (u_int32_t *)0;
int addrcount = 0;
struct tree *addrtree = (struct tree *)0;
struct servent *ent;
int sock;
int pid;
int result;
int flag;
openlog ("dhcpd", LOG_NDELAY, LOG_DAEMON);
#ifndef DEBUG
setlogmask (LOG_UPTO (LOG_INFO));
/* Become a daemon... */
if ((pid = fork ()) < 0)
error ("Can't fork daemon: %m");
else if (pid)
exit (0);
/* Become session leader and get pid... */
pid = setsid ();
#endif
for (i = 1; i < argc; i++) {
if (!strcmp (argv [i], "-p")) {
if (++i == argc)
usage ();
server_port = htons (atoi (argv [i]));
debug ("binding to user-specified port %d\n",
ntohs (server_port));
#if 0
} else if (!strcmp (argv [i], "-a")) {
if (++i == argc)
usage ();
if (inet_aton (argv [i], &addr)) {
addrtree =
tree_concat (addrtree,
tree_const
((unsigned char *)&addr,
sizeof addr));
} else {
addrtree = tree_concat (addrtree,
tree_host_lookup
(argv [i]));
}
#endif
} else
usage ();
}
/* Default to the DHCP/BOOTP port. */
if (!server_port)
{
ent = getservbyname ("dhcp", "udp");
if (!ent)
server_port = htons (67);
else
server_port = ent -> s_port;
endservent ();
}
/* Get the current time... */
GET_TIME (&cur_time);
/* Read the dhcpd.conf file... */
readconf ();
#if 0
/* If addresses were specified on the command line, resolve them;
otherwise, just get a list of the addresses that are configured
on this host and listen on all of them. */
if (addrtree) {
tree_evaluate ((unsigned char **)&addrlist,
&addrcount, addrtree);
addrcount /= 4;
if (!addrcount)
error ("Server addresses resolve to nothing.");
} else {
/* addrlist = get_interface_list (&addrcount); */
#endif
addr.s_addr = 0;
addrlist = (u_int32_t *)&(addr.s_addr);
addrcount = 1;
#if 0
}
#endif
server_addrlist = get_interface_list (&server_addrcount);
/* Listen on the specified (or default) port on each specified
(or default) IP address. */
for (i = 0; i < addrcount; i++) {
listen_on (server_port, addrlist [i]);
}
/* Write a pid file. */
if ((i = open (_PATH_DHCPD_PID, O_WRONLY | O_CREAT)) >= 0) {
char obuf [20];
sprintf (obuf, "%d\n", getpid ());
write (i, obuf, strlen (obuf));
close (i);
}
/* Receive packets and dispatch them... */
dispatch ();
}
/* Print usage message. */
static void usage ()
{
error ("Usage: dhcpd [-p <port>] [-a <ip-addr>]");
}
void cleanup ()
{
}
void do_packet (packbuf, len, from, fromlen, sock)
unsigned char *packbuf;
int len;
struct sockaddr_in *from;
int fromlen;
int sock;
{
struct packet *tp;
struct dhcp_packet *tdp;
if (!(tp = new_packet ("do_packet")))
return;
if (!(tdp = new_dhcp_packet ("do_packet"))) {
free_packet (tp, "do_packet");
return;
}
memcpy (tdp, packbuf, len);
memset (tp, 0, sizeof *tp);
tp -> raw = tdp;
tp -> packet_length = len;
tp -> client = *from;
tp -> client_len = fromlen;
tp -> client_sock = sock;
parse_options (tp);
if (tp -> options_valid &&
tp -> options [DHO_DHCP_MESSAGE_TYPE].data)
dhcp (tp);
else
bootp (tp);
}
dump_packet (tp)
struct packet *tp;
{
struct dhcp_packet *tdp = tp -> raw;
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 yiaddr = %s",
inet_ntoa (tdp -> ciaddr), inet_ntoa (tdp -> yiaddr));
debug ("siaddr = %s giaddr = %s",
inet_ntoa (tdp -> siaddr), 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]);
if (tp -> options_valid) {
int i;
for (i = 0; i < 256; i++) {
if (tp -> options [i].data)
printf (" %s = %s\n",
dhcp_options [i].name,
pretty_print_option
(i, tp -> options [i].data,
tp -> options [i].len));
}
}
}
/* Based on the contents of packet, figure out which interface address
to use from server_addrlist. Currently just picks the first
interface. */
u_int32_t pick_interface (packet)
struct packet *packet;
{
if (server_addrlist)
return server_addrlist [0];
return 0;
}

17
server/dhcpd.conf Normal file
View File

@ -0,0 +1,17 @@
host minuet
hardware ethernet 08:00:2b:35:0c:18
filename "/tftpboot/netbsd.minuet"
fixed-address minuet.fugue.com;
host allegro
hardware ethernet 08:00:2b:1c:07:b6
filename "/tftpboot/netbsd.allegro"
fixed-address allegro.fugue.com;
host fantasia
hardware ethernet 8:0:7:26:c0:a5
fixed-address fantasia.fugue.com
option routers prelude.fugue.com
option name-servers toccata.fugue.com, passacaglia.fugue.com
option domain-name "fugue.com";

208
socket.c Normal file
View File

@ -0,0 +1,208 @@
/* socket.c
BSD socket interface code... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
#include <sys/ioctl.h>
/* List of sockets we're accepting packets on... */
struct socklist {
struct socklist *next;
struct sockaddr_in addr;
int sock;
} *sockets;
/* Return the list of IP addresses associated with each network interface. */
u_int32_t *get_interface_list (count)
int *count;
{
u_int32_t *intbuf = (u_int32_t *)0;
static char buf [8192];
struct ifconf ic;
int i;
int sock;
int ifcount = 0;
int ifix = 0;
/* 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);
close (sock);
if (i < 0)
error ("ioctl: SIOCGIFCONF: %m");
again:
/* Cycle through the list of interfaces looking for IP addresses.
Go through twice; once to count the number if addresses, and a
second time to copy them into an array of addresses. */
for (i = 0; i < ic.ifc_len;) {
struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
if (ifp -> ifr_addr.sa_family == AF_INET) {
struct sockaddr_in *foo =
(struct sockaddr_in *)(&ifp -> ifr_addr);
/* We don't want the loopback interface. */
if (foo -> sin_addr.s_addr == INADDR_LOOPBACK)
continue;
if (intbuf)
intbuf [ifix++] = foo -> sin_addr.s_addr;
else
++ifcount;
}
}
/* If we haven't already filled our array, allocate it and go
again. */
if (!intbuf) {
intbuf = (u_int32_t *)dmalloc ((ifcount + 1)
* sizeof (u_int32_t),
"get_interface_list");
if (!intbuf)
return intbuf;
goto again;
}
*count = ifcount;
return intbuf;
}
void listen_on (port, address)
u_int16_t port;
u_int32_t address;
{
struct sockaddr_in name;
int sock;
struct socklist *tmp;
int flag;
name.sin_family = AF_INET;
name.sin_port = port;
name.sin_addr.s_addr = address;
memset (name.sin_zero, 0, sizeof (name.sin_zero));
/* List addresses on which we're listening. */
note ("Receiving on %s, port %d",
inet_ntoa (name.sin_addr), htons (name.sin_port));
if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
error ("Can't create dhcp socket: %m");
flag = 1;
if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
&flag, sizeof flag) < 0)
error ("Can't set SO_REUSEADDR option on dhcp socket: %m");
if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
&flag, sizeof flag) < 0)
error ("Can't set SO_BROADCAST option on dhcp socket: %m");
if (bind (sock, (struct sockaddr *)&name, sizeof name) < 0)
error ("Can't bind to dhcp address: %m");
tmp = (struct socklist *)dmalloc (sizeof (struct socklist),
"listen_on");
if (!tmp)
error ("Can't allocate memory for socket list.");
tmp -> addr = name;
tmp -> sock = sock;
tmp -> next = sockets;
sockets = tmp;
}
unsigned char packbuf [65536]; /* Should cover the gnarliest MTU... */
void dispatch ()
{
struct sockaddr_in from;
int fromlen = sizeof from;
fd_set r, w, x;
struct socklist *l;
int max = 0;
int count;
int result;
FD_ZERO (&r);
FD_ZERO (&w);
FD_ZERO (&x);
do {
/* Set up the read mask. */
for (l = sockets; l; l = l -> next) {
FD_SET (l -> sock, &r);
FD_SET (l -> sock, &x);
if (l -> sock > max)
max = l -> sock;
}
/* Wait for a packet or a timeout... XXX */
count = select (max + 1, &r, &w, &x, (struct timeval *)0);
/* Not likely to be transitory... */
if (count < 0)
error ("select: %m");
for (l = sockets; l; l = l -> next) {
if (!FD_ISSET (l -> sock, &r))
continue;
if ((result =
recvfrom (l -> sock, packbuf, sizeof packbuf, 0,
(struct sockaddr *)&from, &fromlen))
< 0) {
warn ("recvfrom failed on %s: %m",
inet_ntoa (l -> addr.sin_addr));
sleep (5);
continue;
}
note ("request from %s, port %d",
inet_ntoa (from.sin_addr),
htons (from.sin_port));
do_packet (packbuf, result, &from, fromlen, l -> sock);
}
} while (1);
}

414
tables.c Normal file
View File

@ -0,0 +1,414 @@
/* tables.c
Tables of information... */
/*
* 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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,
"name-servers", "IA", &dhcp_universe, 5,
"domain-name-servers", "IA", &dhcp_universe, 6,
"log-servers", "IA", &dhcp_universe, 7,
"cookie-servers", "IA", &dhcp_universe, 8,
"lpr-servers", "IA", &dhcp_universe, 9,
"impress-servers", "IA", &dhcp_universe, 10,
"resource-location-servers", "IA", &dhcp_universe, 11,
"host-name", "t", &dhcp_universe, 12,
"boot-size", "S", &dhcp_universe, 13,
"merit-dump", "t", &dhcp_universe, 14,
"domain-name", "t", &dhcp_universe, 15,
"swap-server", "I", &dhcp_universe, 16,
"root-path", "t", &dhcp_universe, 17,
"extensions-path", "t", &dhcp_universe, 18,
"ip-forwarding", "f", &dhcp_universe, 19,
"non-local-source-routing", "f", &dhcp_universe, 20,
"policy-filter", "IIA", &dhcp_universe, 21,
"max-dgram-reassembly", "S", &dhcp_universe, 22,
"default-ip-ttl", "B", &dhcp_universe, 23,
"path-mtu-aging-timeout", "L", &dhcp_universe, 24,
"path-mtu-plateau-table", "SA", &dhcp_universe, 25,
"interface-mtu", "S", &dhcp_universe, 26,
"all-subnets-local", "f", &dhcp_universe, 27,
"broadcast-address", "I", &dhcp_universe, 28,
"perform-mask-discovery", "f", &dhcp_universe, 29,
"mask-supplier", "f", &dhcp_universe, 30,
"router-discovery", "f", &dhcp_universe, 31,
"router-solicitation-address", "I", &dhcp_universe, 32,
"static-routes", "IIA", &dhcp_universe, 33,
"trailer-encapsulation", "f", &dhcp_universe, 34,
"arp-cache-timeout", "L", &dhcp_universe, 35,
"ieee802.3-encapsulation", "f", &dhcp_universe, 36,
"default-tcp-ttl", "B", &dhcp_universe, 37,
"tcp-keepalive-interval", "L", &dhcp_universe, 38,
"tcp-keepalive-garbage", "f", &dhcp_universe, 39,
"nis-domain", "t", &dhcp_universe, 40,
"nis-servers", "IA", &dhcp_universe, 41,
"ntp-servers", "IA", &dhcp_universe, 42,
"vendor-encapsulated-options", "t", &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", "t", &dhcp_universe, 61,
"option-62", "", &dhcp_universe, 62,
"option-63", "", &dhcp_universe, 63,
"option-64", "", &dhcp_universe, 64,
"option-65", "", &dhcp_universe, 65,
"option-66", "", &dhcp_universe, 66,
"option-67", "", &dhcp_universe, 67,
"option-68", "", &dhcp_universe, 68,
"option-69", "", &dhcp_universe, 69,
"option-70", "", &dhcp_universe, 70,
"option-71", "", &dhcp_universe, 71,
"option-72", "", &dhcp_universe, 72,
"option-73", "", &dhcp_universe, 73,
"option-74", "", &dhcp_universe, 74,
"option-75", "", &dhcp_universe, 75,
"option-76", "", &dhcp_universe, 76,
"option-77", "", &dhcp_universe, 77,
"option-78", "", &dhcp_universe, 78,
"option-79", "", &dhcp_universe, 79,
"option-80", "", &dhcp_universe, 80,
"option-81", "", &dhcp_universe, 81,
"option-82", "", &dhcp_universe, 82,
"option-83", "", &dhcp_universe, 83,
"option-84", "", &dhcp_universe, 84,
"option-85", "", &dhcp_universe, 85,
"option-86", "", &dhcp_universe, 86,
"option-87", "", &dhcp_universe, 87,
"option-88", "", &dhcp_universe, 88,
"option-89", "", &dhcp_universe, 89,
"option-90", "", &dhcp_universe, 90,
"option-91", "", &dhcp_universe, 91,
"option-92", "", &dhcp_universe, 92,
"option-93", "", &dhcp_universe, 93,
"option-94", "", &dhcp_universe, 94,
"option-95", "", &dhcp_universe, 95,
"option-96", "", &dhcp_universe, 96,
"option-97", "", &dhcp_universe, 97,
"option-98", "", &dhcp_universe, 98,
"option-99", "", &dhcp_universe, 99,
"option-100", "", &dhcp_universe, 100,
"option-101", "", &dhcp_universe, 101,
"option-102", "", &dhcp_universe, 102,
"option-103", "", &dhcp_universe, 103,
"option-104", "", &dhcp_universe, 104,
"option-105", "", &dhcp_universe, 105,
"option-106", "", &dhcp_universe, 106,
"option-107", "", &dhcp_universe, 107,
"option-108", "", &dhcp_universe, 108,
"option-109", "", &dhcp_universe, 109,
"option-110", "", &dhcp_universe, 110,
"option-111", "", &dhcp_universe, 111,
"option-112", "", &dhcp_universe, 112,
"option-113", "", &dhcp_universe, 113,
"option-114", "", &dhcp_universe, 114,
"option-115", "", &dhcp_universe, 115,
"option-116", "", &dhcp_universe, 116,
"option-117", "", &dhcp_universe, 117,
"option-118", "", &dhcp_universe, 118,
"option-119", "", &dhcp_universe, 119,
"option-120", "", &dhcp_universe, 120,
"option-121", "", &dhcp_universe, 121,
"option-122", "", &dhcp_universe, 122,
"option-123", "", &dhcp_universe, 123,
"option-124", "", &dhcp_universe, 124,
"option-125", "", &dhcp_universe, 125,
"option-126", "", &dhcp_universe, 126,
"option-127", "", &dhcp_universe, 127,
"option-128", "", &dhcp_universe, 128,
"option-129", "", &dhcp_universe, 129,
"option-130", "", &dhcp_universe, 130,
"option-131", "", &dhcp_universe, 131,
"option-132", "", &dhcp_universe, 132,
"option-133", "", &dhcp_universe, 133,
"option-134", "", &dhcp_universe, 134,
"option-135", "", &dhcp_universe, 135,
"option-136", "", &dhcp_universe, 136,
"option-137", "", &dhcp_universe, 137,
"option-138", "", &dhcp_universe, 138,
"option-139", "", &dhcp_universe, 139,
"option-140", "", &dhcp_universe, 140,
"option-141", "", &dhcp_universe, 141,
"option-142", "", &dhcp_universe, 142,
"option-143", "", &dhcp_universe, 143,
"option-144", "", &dhcp_universe, 144,
"option-145", "", &dhcp_universe, 145,
"option-146", "", &dhcp_universe, 146,
"option-147", "", &dhcp_universe, 147,
"option-148", "", &dhcp_universe, 148,
"option-149", "", &dhcp_universe, 149,
"option-150", "", &dhcp_universe, 150,
"option-151", "", &dhcp_universe, 151,
"option-152", "", &dhcp_universe, 152,
"option-153", "", &dhcp_universe, 153,
"option-154", "", &dhcp_universe, 154,
"option-155", "", &dhcp_universe, 155,
"option-156", "", &dhcp_universe, 156,
"option-157", "", &dhcp_universe, 157,
"option-158", "", &dhcp_universe, 158,
"option-159", "", &dhcp_universe, 159,
"option-160", "", &dhcp_universe, 160,
"option-161", "", &dhcp_universe, 161,
"option-162", "", &dhcp_universe, 162,
"option-163", "", &dhcp_universe, 163,
"option-164", "", &dhcp_universe, 164,
"option-165", "", &dhcp_universe, 165,
"option-166", "", &dhcp_universe, 166,
"option-167", "", &dhcp_universe, 167,
"option-168", "", &dhcp_universe, 168,
"option-169", "", &dhcp_universe, 169,
"option-170", "", &dhcp_universe, 170,
"option-171", "", &dhcp_universe, 171,
"option-172", "", &dhcp_universe, 172,
"option-173", "", &dhcp_universe, 173,
"option-174", "", &dhcp_universe, 174,
"option-175", "", &dhcp_universe, 175,
"option-176", "", &dhcp_universe, 176,
"option-177", "", &dhcp_universe, 177,
"option-178", "", &dhcp_universe, 178,
"option-179", "", &dhcp_universe, 179,
"option-180", "", &dhcp_universe, 180,
"option-181", "", &dhcp_universe, 181,
"option-182", "", &dhcp_universe, 182,
"option-183", "", &dhcp_universe, 183,
"option-184", "", &dhcp_universe, 184,
"option-185", "", &dhcp_universe, 185,
"option-186", "", &dhcp_universe, 186,
"option-187", "", &dhcp_universe, 187,
"option-188", "", &dhcp_universe, 188,
"option-189", "", &dhcp_universe, 189,
"option-190", "", &dhcp_universe, 190,
"option-191", "", &dhcp_universe, 191,
"option-192", "", &dhcp_universe, 192,
"option-193", "", &dhcp_universe, 193,
"option-194", "", &dhcp_universe, 194,
"option-195", "", &dhcp_universe, 195,
"option-196", "", &dhcp_universe, 196,
"option-197", "", &dhcp_universe, 197,
"option-198", "", &dhcp_universe, 198,
"option-199", "", &dhcp_universe, 199,
"option-200", "", &dhcp_universe, 200,
"option-201", "", &dhcp_universe, 201,
"option-202", "", &dhcp_universe, 202,
"option-203", "", &dhcp_universe, 203,
"option-204", "", &dhcp_universe, 204,
"option-205", "", &dhcp_universe, 205,
"option-206", "", &dhcp_universe, 206,
"option-207", "", &dhcp_universe, 207,
"option-208", "", &dhcp_universe, 208,
"option-209", "", &dhcp_universe, 209,
"option-210", "", &dhcp_universe, 210,
"option-211", "", &dhcp_universe, 211,
"option-212", "", &dhcp_universe, 212,
"option-213", "", &dhcp_universe, 213,
"option-214", "", &dhcp_universe, 214,
"option-215", "", &dhcp_universe, 215,
"option-216", "", &dhcp_universe, 216,
"option-217", "", &dhcp_universe, 217,
"option-218", "", &dhcp_universe, 218,
"option-219", "", &dhcp_universe, 219,
"option-220", "", &dhcp_universe, 220,
"option-221", "", &dhcp_universe, 221,
"option-222", "", &dhcp_universe, 222,
"option-223", "", &dhcp_universe, 223,
"option-224", "", &dhcp_universe, 224,
"option-225", "", &dhcp_universe, 225,
"option-226", "", &dhcp_universe, 226,
"option-227", "", &dhcp_universe, 227,
"option-228", "", &dhcp_universe, 228,
"option-229", "", &dhcp_universe, 229,
"option-230", "", &dhcp_universe, 230,
"option-231", "", &dhcp_universe, 231,
"option-232", "", &dhcp_universe, 232,
"option-233", "", &dhcp_universe, 233,
"option-234", "", &dhcp_universe, 234,
"option-235", "", &dhcp_universe, 235,
"option-236", "", &dhcp_universe, 236,
"option-237", "", &dhcp_universe, 237,
"option-238", "", &dhcp_universe, 238,
"option-239", "", &dhcp_universe, 239,
"option-240", "", &dhcp_universe, 240,
"option-241", "", &dhcp_universe, 241,
"option-242", "", &dhcp_universe, 242,
"option-243", "", &dhcp_universe, 243,
"option-244", "", &dhcp_universe, 244,
"option-245", "", &dhcp_universe, 245,
"option-246", "", &dhcp_universe, 246,
"option-247", "", &dhcp_universe, 247,
"option-248", "", &dhcp_universe, 248,
"option-249", "", &dhcp_universe, 249,
"option-250", "", &dhcp_universe, 250,
"option-251", "", &dhcp_universe, 251,
"option-252", "", &dhcp_universe, 252,
"option-253", "", &dhcp_universe, 253,
"option-254", "", &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_SUBNET_MASK,
DHO_TIME_OFFSET,
DHO_ROUTERS,
DHO_TIME_SERVERS,
DHO_NAME_SERVERS,
DHO_DOMAIN_NAME_SERVERS,
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_REQUESTED_ADDRESS,
DHO_DHCP_LEASE_TIME,
DHO_DHCP_OPTION_OVERLOAD,
DHO_DHCP_MESSAGE_TYPE,
DHO_DHCP_SERVER_IDENTIFIER,
DHO_DHCP_PARAMETER_REQUEST_LIST,
DHO_DHCP_MESSAGE,
DHO_DHCP_MAX_MESSAGE_SIZE,
DHO_DHCP_RENEWAL_TIME,
DHO_DHCP_REBINDING_TIME,
DHO_DHCP_CLASS_IDENTIFIER,
DHO_DHCP_CLIENT_IDENTIFIER,
};
int sizeof_dhcp_option_default_priority_list =
sizeof dhcp_option_default_priority_list;
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, dhcp_options [i].name, 0,
(unsigned char *)&dhcp_options [i]);
}
universe_hash.hash_count = DEFAULT_HASH_SIZE;
add_hash (&universe_hash, dhcp_universe.name, 0,
(unsigned char *)&dhcp_universe);
}

391
tree.c Normal file
View File

@ -0,0 +1,391 @@
/* tree.c
Routines for manipulating parse 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''.
*/
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1995 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 = (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 -> 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;
debug ("time: now = %d dns = %d %d diff = %d",
cur_time, dns -> timeout, cur_time - dns -> timeout);
/* If the record hasn't timed out, just copy the data and return. */
if (cur_time <= dns -> timeout) {
debug ("easy copy: %x %d %x",
dns -> data, dns -> data_len, *(int *)(dns -> data));
do_data_copy (bufix, bufp, bufcount,
dns -> data, dns -> data_len);
return dns -> timeout;
}
debug ("Looking up %s", dns -> hostname);
/* Otherwise, look it up... */
h = gethostbyname (dns -> hostname);
if (!h) {
switch (h_errno) {
case HOST_NOT_FOUND:
warn ("%s: host unknown.", dns -> hostname);
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);
}
/* Okay to try again after a minute. */
return cur_time + 60;
}
debug ("Lookup succeeded; first address is %x",
h -> h_addr_list [0]);
/* 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 {
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);
debug ("dns -> data: %x h -> h_addr_list [0]: %x",
*(int *)(dns -> data), h -> h_addr_list [0]);
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;
debug ("hard copy: %x %d %x",
dns -> data, dns -> data_len, *(int *)(dns -> data));
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;
}

104
tree.h Normal file
View File

@ -0,0 +1,104 @@
/* 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;
};
struct universe {
char *name;
struct hash_table *hash;
struct option *options [256];
};
struct option {
char *name;
char *format;
struct universe *universe;
unsigned char code;
};