First import of DHCP client service.

No pipe created yet.  Event model up and running.
Does not produce a dhcp offer yet but working on that.

svn path=/trunk/; revision=14496
This commit is contained in:
Art Yerkes 2005-04-04 23:45:33 +00:00
parent e26cc4962b
commit cb76d1fab2
34 changed files with 8253 additions and 0 deletions

View file

@ -0,0 +1,30 @@
#
PATH_TO_TOP = ../../..
TARGET_TYPE = program
TARGET_APPTYPE = windows
TARGET_NAME = dhcp
TARGET_CFLAGS = -D__REACTOS__ -D_WIN32_WINNT=0x0501 -D__USE_W32API -Iinclude
TARGET_OBJECTS = adapter.o alloc.o compat.o dhclient.o dispatch.o hash.o \
options.o privsep.o socket.o tables.o timer.o util.o
TARGET_SDKLIBS = iphlpapi.a ws2_32.a ntdll.a
TARGET_RC_SRCS = dhcp.rc
TARGET_RC_BINSRC =
TARGET_RC_BINARIES =
default: all
DEP_OBJECTS = $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
include $(TOOLS_PATH)/depend.mk

View file

@ -0,0 +1,162 @@
#include "rosdhcp.h"
static LIST_ENTRY AdapterList;
static WSADATA wsd;
extern struct interface_info *ifi;
DWORD GetAddress( PDHCP_ADAPTER Adapter ) {
PMIB_IPADDRTABLE AddressTable = NULL;
ULONG i, Size = 0, NumAddressRows;
DWORD Error = GetIpAddrTable( AddressTable, &Size, FALSE );
while( Error == ERROR_INSUFFICIENT_BUFFER ) {
free( AddressTable );
AddressTable = malloc( Size );
if( AddressTable )
Error = GetIpAddrTable( AddressTable, &Size, FALSE );
}
if( Error != ERROR_SUCCESS ) {
free( AddressTable );
return Error;
}
NumAddressRows = Size / sizeof(MIB_IPADDRTABLE);
for( i = 0; i < AddressTable->dwNumEntries; i++ ) {
DH_DbgPrint(MID_TRACE,
("Finding address for adapter %d: (%d -> %x)\n",
Adapter->IfMib.dwIndex,
AddressTable->table[i].dwIndex,
AddressTable->table[i].dwAddr));
if( Adapter->IfMib.dwIndex == AddressTable->table[i].dwIndex ) {
memcpy( &Adapter->IfAddr, &AddressTable->table[i],
sizeof( MIB_IPADDRROW ) );
}
}
}
void AdapterInit() {
PMIB_IFTABLE Table = malloc(sizeof(MIB_IFTABLE));
DWORD Error, Size, i;
PDHCP_ADAPTER Adapter = NULL;
WSAStartup(0x0101,&wsd);
InitializeListHead( &AdapterList );
DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
while( (Error = GetIfTable(Table, &Size, 0 )) ==
ERROR_INSUFFICIENT_BUFFER ) {
DH_DbgPrint(MID_TRACE,("Error %d, New Buffer Size: %d\n", Error, Size));
free( Table );
Table = malloc( Size );
}
if( Error != NO_ERROR ) goto term;
DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));
for( i = 0; i < Table->dwNumEntries; i++ ) {
DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n", i));
Adapter = calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );
if( Adapter ) {
memcpy( &Adapter->IfMib, &Table->table[i],
sizeof(Adapter->IfMib) );
GetAddress( Adapter );
InsertTailList( &AdapterList, &Adapter->ListEntry );
Adapter->DhclientInfo.next = ifi;
Adapter->DhclientInfo.client = &Adapter->DhclientState;
Adapter->DhclientInfo.rbuf = Adapter->recv_buf;
Adapter->DhclientInfo.rbuf_max = Table->table[i].dwMtu;
Adapter->DhclientInfo.rbuf_len =
Adapter->DhclientInfo.rbuf_offset = 0;
Adapter->DhclientInfo.rfdesc =
Adapter->DhclientInfo.wfdesc =
socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
Adapter->ListenAddr.sin_family = AF_INET;
Adapter->ListenAddr.sin_port = htons(LOCAL_PORT);
Adapter->BindStatus =
(bind( Adapter->DhclientInfo.rfdesc,
(struct sockaddr *)&Adapter->ListenAddr,
sizeof(Adapter->ListenAddr) ) == 0) ?
0 : WSAGetLastError();
Adapter->DhclientState.config = &Adapter->DhclientConfig;
Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL;
Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL;
Adapter->DhclientConfig.select_interval = 1;
Adapter->DhclientConfig.reboot_timeout = DHCP_REBOOT_TIMEOUT;
Adapter->DhclientConfig.backoff_cutoff = DHCP_BACKOFF_MAX;
Adapter->DhclientState.interval =
Adapter->DhclientConfig.retry_interval;
strncpy(Adapter->DhclientInfo.name, Adapter->IfMib.bDescr,
sizeof(Adapter->DhclientInfo.name));
DH_DbgPrint(MID_TRACE,("Adapter Name: [%s]\n", Adapter->DhclientInfo.name));
ifi = &Adapter->DhclientInfo;
}
}
DH_DbgPrint(MID_TRACE,("done with AdapterInit\n"));
term:
if( Table ) free( Table );
}
void AdapterStop() {
PLIST_ENTRY ListEntry;
PDHCP_ADAPTER Adapter;
while( !IsListEmpty( &AdapterList ) ) {
ListEntry = (PLIST_ENTRY)RemoveHeadList( &AdapterList );
Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
free( Adapter );
}
WSACleanup();
}
PDHCP_ADAPTER AdapterFindIndex( unsigned int indx ) {
PDHCP_ADAPTER Adapter;
PLIST_ENTRY ListEntry;
for( ListEntry = AdapterList.Flink;
ListEntry != &AdapterList;
ListEntry = ListEntry->Flink ) {
Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
if( Adapter->IfMib.dwIndex == indx ) return Adapter;
}
return NULL;
}
PDHCP_ADAPTER AdapterFindName( const WCHAR *name ) {
PDHCP_ADAPTER Adapter;
PLIST_ENTRY ListEntry;
for( ListEntry = AdapterList.Flink;
ListEntry != &AdapterList;
ListEntry = ListEntry->Flink ) {
Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
if( !wcsicmp( Adapter->IfMib.wszName, name ) ) return Adapter;
}
return NULL;
}
PDHCP_ADAPTER AdapterGetFirst() {
if( IsListEmpty( &AdapterList ) ) return NULL; else {
return CONTAINING_RECORD
( AdapterList.Flink, DHCP_ADAPTER, ListEntry );
}
}
PDHCP_ADAPTER AdapterGetNext( PDHCP_ADAPTER This )
{
if( This->ListEntry.Flink == &AdapterList ) return NULL;
return CONTAINING_RECORD
( This->ListEntry.Flink, DHCP_ADAPTER, ListEntry );
}
void if_register_send(struct interface_info *ip) {
}
void if_register_receive(struct interface_info *ip) {
}

View file

@ -0,0 +1,79 @@
/* $OpenBSD: alloc.c,v 1.9 2004/05/04 20:28:40 deraadt Exp $ */
/* Memory allocation... */
/*
* Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <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 "rosdhcp.h"
#include "dhcpd.h"
struct string_list *
new_string_list(size_t size)
{
struct string_list *rval;
rval = calloc(1, sizeof(struct string_list) + size);
if (rval != NULL)
rval->string = ((char *)rval) + sizeof(struct string_list);
return (rval);
}
struct hash_table *
new_hash_table(int count)
{
struct hash_table *rval;
rval = calloc(1, sizeof(struct hash_table) -
(DEFAULT_HASH_SIZE * sizeof(struct hash_bucket *)) +
(count * sizeof(struct hash_bucket *)));
if (rval == NULL)
return (NULL);
rval->hash_count = count;
return (rval);
}
struct hash_bucket *
new_hash_bucket(void)
{
struct hash_bucket *rval = calloc(1, sizeof(struct hash_bucket));
return (rval);
}
void free_hash_bucket(struct hash_bucket *hb) { free(hb); }

View file

@ -0,0 +1,40 @@
#include "rosdhcp.h"
#include "dhcpd.h"
#include "stdint.h"
size_t strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len = strlen(s);
size_t ret = len;
if (bufsize > 0) {
if (len >= bufsize)
len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
}
return ret;
}
// not really random :(
u_int32_t arc4random()
{
static int did_srand = 0;
u_int32_t ret;
if (!did_srand) {
srand(0);
did_srand = 1;
}
ret = rand() << 10 ^ rand();
return ret;
}
int inet_aton(const char *cp, struct in_addr *inp)
{
inp->S_un.S_addr = inet_addr(cp);
if (INADDR_NONE == inp->S_un.S_addr)
return 0;
return 1;
}

View file

@ -0,0 +1,29 @@
Ok I need these things:
1) Adapter concept thingy
Needs a name and index
Current IP address etc
interface_info
Must be able to get one from an adapter index or name
Must query the ip address and such
Must be able to set the address
2) System state doodad
List of adapters
List of parameter changes
List of persistent stuff
Must be able to initialize from the registry
(persistent stuff, some adapter info)
Save changes to persistent set
3) Parameter change set
TODO
4) Persistent queries
TODO

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
/* $Id: regsvr32.rc 12852 2005-01-06 13:58:04Z mf $ */
#define REACTOS_STR_FILE_DESCRIPTION "DHCP Client Service"
#define REACTOS_STR_INTERNAL_NAME "dhcp\0"
#define REACTOS_STR_ORIGINAL_FILENAME "dhcp.exe\0"
#include <reactos/version.rc>

View file

@ -0,0 +1,72 @@
/* $Id:$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Service
* FILE: subsys/system/dhcp
* PURPOSE: DHCP client service entry point
* PROGRAMMER: Art Yerkes (arty@users.sf.net)
* UPDATE HISTORY:
* Created 03/08/2005
*/
#include <windows.h>
#include "dhcpd.h"
#include "version.h"
typedef struct _DHCP_API_REQUEST {
int type;
UINT flags;
LPDHCPAPI_CLASSID class_id;
DHCP_API_PARAMS_ARRAY vendor_params;
DHCP_API_PARAMS_ARRAY general_params;
LPWSTR request_id, adapter_name;
} DHCP_API_REQUEST;
typedef struct _DHCP_MANAGED_ADAPTER {
LPWSTR adapter_name, hostname, dns_server;
UINT adapter_index;
struct sockaddr_in address, netmask;
struct interface_info *dhcp_info;
} DHCP_MANAGED_ADAPTER;
#define DHCP_REQUESTPARAM WM_USER + 0
#define DHCP_PARAMCHANGE WM_USER + 1
#define DHCP_CANCELREQUEST WM_USER + 2
#define DHCP_NOPARAMCHANGE WM_USER + 3
#define DHCP_MANAGEADAPTER WM_USER + 4
#define DHCP_UNMANAGEADAPTER WM_USER + 5
UINT DhcpEventTimer;
HANDLE DhcpServiceThread;
DWORD DhcpServiceThreadId;
LIST_ENTRY ManagedAdapters;
LRESULT WINAPI ServiceThread( PVOID Data ) {
MSG msg;
while( GetMessage( &msg, 0, 0, 0 ) ) {
switch( msg.message ) {
case DHCP_MANAGEADAPTER:
break;
case DHCP_UNMANAGEADAPTER:
break;
case DHCP_REQUESTPARAM:
break;
case DHCP_CANCELREQUEST:
break;
case DHCP_PARAMCHANGE:
break;
case DHCP_NOPARAMCHANGE:
break;
}
}
}
int main( int argc, char **argv ) {
}

View file

@ -0,0 +1,579 @@
/* $OpenBSD: dispatch.c,v 1.31 2004/09/21 04:07:03 david Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
* Copyright (c) 1995, 1996, 1997, 1998, 1999
* The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#include "rosdhcp.h"
#include "dhcpd.h"
//#include <sys/ioctl.h>
//#include <net/if_media.h>
//#include <ifaddrs.h>
//#include <poll.h>
struct protocol *protocols = NULL;
struct timeout *timeouts = NULL;
static struct timeout *free_timeouts = NULL;
static int interfaces_invalidated = FALSE;
void (*bootp_packet_handler)(struct interface_info *,
struct dhcp_packet *, int, unsigned int,
struct iaddr, struct hardware *);
static int interface_status(struct interface_info *ifinfo);
/*
* Use getifaddrs() to get a list of all the attached interfaces. For
* each interface that's of type INET and not the loopback interface,
* register that interface with the network I/O software, figure out
* what subnet it's on, and add it to the list of interfaces.
*/
#if 0
void
discover_interfaces(struct interface_info *iface)
{
struct ifaddrs *ifap, *ifa;
struct sockaddr_in foo;
struct ifreq *tif;
if (getifaddrs(&ifap) != 0)
error("getifaddrs failed");
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
if ((ifa->ifa_flags & IFF_LOOPBACK) ||
(ifa->ifa_flags & IFF_POINTOPOINT) ||
(!(ifa->ifa_flags & IFF_UP)))
continue;
if (strcmp(iface->name, ifa->ifa_name))
continue;
/*
* If we have the capability, extract link information
* and record it in a linked list.
*/
if (ifa->ifa_addr->sa_family == AF_LINK) {
struct sockaddr_dl *foo =
(struct sockaddr_dl *)ifa->ifa_addr;
iface->index = foo->sdl_index;
iface->hw_address.hlen = foo->sdl_alen;
iface->hw_address.htype = HTYPE_ETHER; /* XXX */
memcpy(iface->hw_address.haddr,
LLADDR(foo), foo->sdl_alen);
} else if (ifa->ifa_addr->sa_family == AF_INET) {
struct iaddr addr;
memcpy(&foo, ifa->ifa_addr, sizeof(foo));
if (foo.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
continue;
if (!iface->ifp) {
int len = IFNAMSIZ + ifa->ifa_addr->sa_len;
if ((tif = malloc(len)) == NULL)
error("no space to remember ifp");
strlcpy(tif->ifr_name, ifa->ifa_name, IFNAMSIZ);
memcpy(&tif->ifr_addr, ifa->ifa_addr,
ifa->ifa_addr->sa_len);
iface->ifp = tif;
iface->primary_address = foo.sin_addr;
}
addr.len = 4;
memcpy(addr.iabuf, &foo.sin_addr.s_addr, addr.len);
}
}
if (!iface->ifp)
error("%s: not found", iface->name);
/* Register the interface... */
if_register_receive(iface);
if_register_send(iface);
add_protocol(iface->name, iface->rfdesc, got_one, iface);
freeifaddrs(ifap);
}
#else
void
discover_interfaces(struct interface_info *iface)
{
NTSTATUS Status;
ULONG dim;
char TmpName [IFNAMSIZ];
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
pAdapterInfo = malloc(sizeof(IP_ADAPTER_INFO));
dim = sizeof(IP_ADAPTER_INFO);
if (GetAdaptersInfo( pAdapterInfo, &dim) != ERROR_SUCCESS) {
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) malloc (dim);
}
if ((Status = GetAdaptersInfo( pAdapterInfo, &dim)) != NO_ERROR) {
note("Error %x", Status);
free (pAdapterInfo);
return;
}
for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
/* we only do ethernet */
note("found: %s %x\n", pAdapter->AdapterName, pAdapter->Address);
if (pAdapter->Type != MIB_IF_TYPE_ETHERNET) {
continue;
}
note ("found ethernet\n");
iface->hw_address.hlen = pAdapter->AddressLength;
iface->hw_address.htype = HTYPE_ETHER;
memcpy (&iface->hw_address.haddr[0],
pAdapter->Address, iface->hw_address.hlen);
if (pAdapter->IpAddressList.IpAddress.String)
iface->primary_address.S_un.S_addr = inet_addr(pAdapter->IpAddressList.IpAddress.String);
}
if (iface) {
if_register_receive(iface);
if_register_send(iface);
add_protocol(iface->name, iface->rfdesc, got_one, iface);
}
free (pAdapterInfo);
}
#endif
void
reinitialize_interfaces(void)
{
interfaces_invalidated = 1;
}
/*
* Wait for packets to come in using poll(). When a packet comes in,
* call receive_packet to receive the packet and possibly strip hardware
* addressing information from it, and then call through the
* bootp_packet_handler hook to try to do something with it.
*/
void
dispatch(void)
{
int count, i, to_msec, nfds = 0;
struct protocol *l;
fd_set fds;
time_t howlong;
struct timeval timeval;
for (l = protocols; l; l = l->next)
nfds++;
FD_ZERO(&fds);
// fds = malloc(nfds * sizeof(struct pollfd));
// if (fds == NULL)
// error("Can't allocate poll structures.");
do {
DH_DbgPrint(MID_TRACE,("Cycling dispatch()\n"));
/*
* Call any expired timeouts, and then if there's still
* a timeout registered, time out the select call then.
*/
another:
if (timeouts) {
DH_DbgPrint(MID_TRACE,("Some timeouts are available\n"));
struct timeout *t;
if (timeouts->when <= cur_time) {
DH_DbgPrint(MID_TRACE,("Calling timeout %x %p %x\n",
timeouts->when,
timeouts->func,
timeouts->what));
t = timeouts;
timeouts = timeouts->next;
(*(t->func))(t->what);
t->next = free_timeouts;
free_timeouts = t;
goto another;
}
/*
* Figure timeout in milliseconds, and check for
* potential overflow, so we can cram into an
* int for poll, while not polling with a
* negative timeout and blocking indefinitely.
*/
howlong = timeouts->when - cur_time;
if (howlong > INT_MAX / 1000)
howlong = INT_MAX / 1000;
to_msec = howlong * 1000;
} else
to_msec = -1;
/* Set up the descriptors to be polled. */
for (i = 0, l = protocols; l; l = l->next) {
struct interface_info *ip = l->local;
if (ip && (l->handler != got_one || !ip->dead)) {
DH_DbgPrint(MID_TRACE,("l->fd %d\n", l->fd));
FD_SET(l->fd, &fds);
// fds[i].fd = l->fd;
// fds[i].events = POLLIN;
// fds[i].revents = 0;
i++;
}
}
if (i == 0)
error("No live interfaces to poll on - exiting.");
/* Wait for a packet or a timeout... XXX */
timeval.tv_sec = to_msec / 1000;
timeval.tv_usec = (to_msec % 1000) * 1000;
DH_DbgPrint(MID_TRACE,("select(%d,%d.%03d) =>\n",
nfds,timeval.tv_sec,timeval.tv_usec/1000));
count = select(nfds, &fds, NULL, NULL, &timeval);
DH_DbgPrint(MID_TRACE,(" => %d\n", count));
/* Not likely to be transitory... */
if (count == SOCKET_ERROR) {
if (errno == EAGAIN || errno == EINTR) {
time(&cur_time);
continue;
} else
error("poll: %m");
}
/* Get the current time... */
time(&cur_time);
i = 0;
for (l = protocols; l; l = l->next) {
struct interface_info *ip;
ip = l->local;
if (!FD_ISSET(l->fd, &fds)) {
//.revents & (POLLIN | POLLHUP))) {
// fds[i].revents = 0;
if (ip && (l->handler != got_one ||
!ip->dead)) {
DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
(*(l->handler))(l);
if (interfaces_invalidated)
break;
}
i++;
}
interfaces_invalidated = 0;
}
DH_DbgPrint(MID_TRACE,("Done\n"));
} while (1);
}
void
got_one(struct protocol *l)
{
struct sockaddr_in from;
struct hardware hfrom;
struct iaddr ifrom;
ssize_t result;
union {
/*
* Packet input buffer. Must be as large as largest
* possible MTU.
*/
unsigned char packbuf[4095];
struct dhcp_packet packet;
} u;
struct interface_info *ip = l->local;
if ((result = receive_packet(ip, u.packbuf, sizeof(u), &from,
&hfrom)) == -1) {
warning("receive_packet failed on %s: %s", ip->name,
strerror(errno));
ip->errors++;
if ((!interface_status(ip)) ||
(ip->noifmedia && ip->errors > 20)) {
/* our interface has gone away. */
warning("Interface %s no longer appears valid.",
ip->name);
ip->dead = 1;
interfaces_invalidated = 1;
close(l->fd);
remove_protocol(l);
free(ip);
}
return;
}
if (result == 0)
return;
if (bootp_packet_handler) {
ifrom.len = 4;
memcpy(ifrom.iabuf, &from.sin_addr, ifrom.len);
(*bootp_packet_handler)(ip, &u.packet, result,
from.sin_port, ifrom, &hfrom);
}
}
#if 0
int
interface_status(struct interface_info *ifinfo)
{
char *ifname = ifinfo->name;
int ifsock = ifinfo->rfdesc;
struct ifreq ifr;
struct ifmediareq ifmr;
/* get interface flags */
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(ifsock, SIOCGIFFLAGS, &ifr) < 0) {
syslog(LOG_ERR, "ioctl(SIOCGIFFLAGS) on %s: %m", ifname);
goto inactive;
}
/*
* if one of UP and RUNNING flags is dropped,
* the interface is not active.
*/
if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
goto inactive;
/* Next, check carrier on the interface, if possible */
if (ifinfo->noifmedia)
goto active;
memset(&ifmr, 0, sizeof(ifmr));
strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
if (ioctl(ifsock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
if (errno != EINVAL) {
syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
ifname);
ifinfo->noifmedia = 1;
goto active;
}
/*
* EINVAL (or ENOTTY) simply means that the interface
* does not support the SIOCGIFMEDIA ioctl. We regard it alive.
*/
ifinfo->noifmedia = 1;
goto active;
}
if (ifmr.ifm_status & IFM_AVALID) {
switch (ifmr.ifm_active & IFM_NMASK) {
case IFM_ETHER:
if (ifmr.ifm_status & IFM_ACTIVE)
goto active;
else
goto inactive;
break;
default:
goto inactive;
}
}
inactive:
return (0);
active:
return (1);
}
#else
int
interface_status(struct interface_info *ifinfo)
{
return (1);
}
#endif
void
add_timeout(time_t when, void (*where)(void *), void *what)
{
struct timeout *t, *q;
DH_DbgPrint(MID_TRACE,("Adding timeout %x %p %x\n", when, where, what));
/* See if this timeout supersedes an existing timeout. */
t = NULL;
for (q = timeouts; q; q = q->next) {
if (q->func == where && q->what == what) {
if (t)
t->next = q->next;
else
timeouts = q->next;
break;
}
t = q;
}
/* If we didn't supersede a timeout, allocate a timeout
structure now. */
if (!q) {
if (free_timeouts) {
q = free_timeouts;
free_timeouts = q->next;
q->func = where;
q->what = what;
} else {
q = malloc(sizeof(struct timeout));
if (!q)
error("Can't allocate timeout structure!");
q->func = where;
q->what = what;
}
}
q->when = when;
/* Now sort this timeout into the timeout list. */
/* Beginning of list? */
if (!timeouts || timeouts->when > q->when) {
q->next = timeouts;
timeouts = q;
return;
}
/* Middle of list? */
for (t = timeouts; t->next; t = t->next) {
if (t->next->when > q->when) {
q->next = t->next;
t->next = q;
return;
}
}
/* End of list. */
t->next = q;
q->next = NULL;
}
void
cancel_timeout(void (*where)(void *), void *what)
{
struct timeout *t, *q;
/* Look for this timeout on the list, and unlink it if we find it. */
t = NULL;
for (q = timeouts; q; q = q->next) {
if (q->func == where && q->what == what) {
if (t)
t->next = q->next;
else
timeouts = q->next;
break;
}
t = q;
}
/* If we found the timeout, put it on the free list. */
if (q) {
q->next = free_timeouts;
free_timeouts = q;
}
}
/* Add a protocol to the list of protocols... */
void
add_protocol(char *name, int fd, void (*handler)(struct protocol *),
void *local)
{
struct protocol *p;
p = malloc(sizeof(*p));
if (!p)
error("can't allocate protocol struct for %s", name);
p->fd = fd;
p->handler = handler;
p->local = local;
p->next = protocols;
protocols = p;
}
void
remove_protocol(struct protocol *proto)
{
struct protocol *p, *next, *prev;
prev = NULL;
for (p = protocols; p; p = next) {
next = p->next;
if (p == proto) {
if (prev)
prev->next = p->next;
else
protocols = p->next;
free(p);
}
}
}
int
interface_link_status(char *ifname)
{
#if 0
struct ifmediareq ifmr;
int sock;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
error("Can't create socket");
memset(&ifmr, 0, sizeof(ifmr));
strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
/* EINVAL -> link state unknown. treat as active */
if (errno != EINVAL)
syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
ifname);
close(sock);
return (1);
}
close(sock);
if (ifmr.ifm_status & IFM_AVALID) {
if ((ifmr.ifm_active & IFM_NMASK) == IFM_ETHER) {
if (ifmr.ifm_status & IFM_ACTIVE)
return (1);
else
return (0);
}
}
#endif
return (1);
}

View file

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

View file

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

View file

@ -0,0 +1,84 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/debug.h
* PURPOSE: Debugging support macros
* DEFINES: DBG - Enable debug output
* NASSERT - Disable assertions
*/
#ifndef __DEBUG_H
#define __DEBUG_H
#define NORMAL_MASK 0x000000FF
#define SPECIAL_MASK 0xFFFFFF00
#define MIN_TRACE 0x00000001
#define MID_TRACE 0x00000002
#define MAX_TRACE 0x00000003
#define DEBUG_ADAPTER 0x00000100
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG
extern unsigned long debug_trace_level;
#ifdef _MSC_VER
#define DH_DbgPrint(_t_, _x_) \
if (((debug_trace_level & NORMAL_MASK) >= _t_) || \
((debug_trace_level & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d) ", __FILE__, __LINE__); \
DbgPrint _x_ ; \
}
#else /* _MSC_VER */
#define DH_DbgPrint(_t_, _x_) \
if (((debug_trace_level & NORMAL_MASK) >= _t_) || \
((debug_trace_level & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
DbgPrint _x_ ; \
}
#endif /* _MSC_VER */
#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
#else /* DBG */
#define DH_DbgPrint(_t_, _x_)
#endif /* DBG */
#define assert(x) ASSERT(x)
#define assert_irql(x) ASSERT_IRQL(x)
#ifdef _MSC_VER
#define UNIMPLEMENTED \
TI_DbgPrint(MIN_TRACE, ("The function at %s:%d is unimplemented, \
but come back another day.\n", __FILE__, __LINE__));
#else /* _MSC_VER */
#define UNIMPLEMENTED \
TI_DbgPrint(MIN_TRACE, ("(%s:%d)(%s) is unimplemented, \
but come back another day.\n", __FILE__, __LINE__, __FUNCTION__));
#endif /* _MSC_VER */
#define CHECKPOINT \
do { TI_DbgPrint(DEBUG_CHECK, ("(%s:%d)\n", __FILE__, __LINE__)); } while(0);
#define CP CHECKPOINT
#define ASSERT_KM_POINTER(_x) \
ASSERT(((PVOID)_x) != (PVOID)0xcccccccc); \
ASSERT(((PVOID)_x) >= (PVOID)0x80000000);
#endif /* __DEBUG_H */
/* EOF */

View file

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

View file

@ -0,0 +1,487 @@
/* $OpenBSD: dhcpd.h,v 1.33 2004/05/06 22:29:15 deraadt Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
* Copyright (c) 1995, 1996, 1997, 1998, 1999
* The Internet Software Consortium. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The Internet Software Consortium nor the names
* of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This software has been written for the Internet Software Consortium
* by Ted Lemon <mellon@fugue.com> in cooperation with Vixie
* Enterprises. To learn more about the Internet Software Consortium,
* see ``http://www.vix.com/isc''. To learn more about Vixie
* Enterprises, see ``http://www.vix.com''.
*/
#ifndef DHCPD_H
#define DHCPD_H
#include <winsock2.h>
#include <iphlpapi.h>
#include "stdint.h"
#define IFNAMSIZ MAX_INTERFACE_NAME_LEN
#define ETH_ALEN 6
#define ETHER_ADDR_LEN ETH_ALEN
struct ether_header
{
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
u_int16_t ether_type; /* packet type ID field */
} __attribute__ ((__packed__));
struct ip
{
unsigned int ip_hl:4; /* header length */
unsigned int ip_v:4; /* version */
u_int8_t ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
struct udphdr {
u_int16_t uh_sport; /* source port */
u_int16_t uh_dport; /* destination port */
u_int16_t uh_ulen; /* udp length */
u_int16_t uh_sum; /* udp checksum */
};
#define ETHERTYPE_IP 0x0800
#define IPTOS_LOWDELAY 0x10
#define ARPHRD_ETHER 1
// FIXME: I have no idea what this should be!
#define SIZE_T_MAX 1600
#define USE_SOCKET_RECEIVE
#define USE_SOCKET_SEND
#include <sys/types.h>
//#include <sys/socket.h>
//#include <sys/sockio.h>
#include <sys/stat.h>
#include <sys/time.h>
//#include <sys/un.h>
//#include <sys/wait.h>
//#include <net/if.h>
//#include <net/if_dl.h>
//#include <net/route.h>
//#include <netinet/in.h>
//#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
//#include <netdb.h>
//#include <paths.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <syslog.h>
#include <time.h>
#include <unistd.h>
#include "dhcp.h"
#include "tree.h"
#define LOCAL_PORT 68
#define REMOTE_PORT 67
struct option_data {
int len;
u_int8_t *data;
};
struct string_list {
struct string_list *next;
char *string;
};
struct iaddr {
int len;
unsigned char iabuf[16];
};
struct iaddrlist {
struct iaddrlist *next;
struct iaddr addr;
};
struct packet {
struct dhcp_packet *raw;
int packet_length;
int packet_type;
int options_valid;
int client_port;
struct iaddr client_addr;
struct interface_info *interface;
struct hardware *haddr;
struct option_data options[256];
};
struct hardware {
u_int8_t htype;
u_int8_t hlen;
u_int8_t haddr[16];
};
struct client_lease {
struct client_lease *next;
time_t expiry, renewal, rebind;
struct iaddr address;
char *server_name;
char *filename;
struct string_list *medium;
unsigned int is_static : 1;
unsigned int is_bootp : 1;
struct option_data options[256];
};
/* Possible states in which the client can be. */
enum dhcp_state {
S_REBOOTING,
S_INIT,
S_SELECTING,
S_REQUESTING,
S_BOUND,
S_RENEWING,
S_REBINDING
};
struct client_config {
struct option_data defaults[256];
enum {
ACTION_DEFAULT,
ACTION_SUPERSEDE,
ACTION_PREPEND,
ACTION_APPEND
} default_actions[256];
struct option_data send_options[256];
u_int8_t required_options[256];
u_int8_t requested_options[256];
int requested_option_count;
time_t timeout;
time_t initial_interval;
time_t retry_interval;
time_t select_interval;
time_t reboot_timeout;
time_t backoff_cutoff;
struct string_list *media;
char *script_name;
enum { IGNORE, ACCEPT, PREFER }
bootp_policy;
struct string_list *medium;
struct iaddrlist *reject_list;
};
struct client_state {
struct client_lease *active;
struct client_lease *new;
struct client_lease *offered_leases;
struct client_lease *leases;
struct client_lease *alias;
enum dhcp_state state;
struct iaddr destination;
u_int32_t xid;
u_int16_t secs;
time_t first_sending;
time_t interval;
struct string_list *medium;
struct dhcp_packet packet;
int packet_length;
struct iaddr requested_address;
struct client_config *config;
};
struct interface_info {
struct interface_info *next;
struct hardware hw_address;
struct in_addr primary_address;
char name[IFNAMSIZ];
int rfdesc;
int wfdesc;
unsigned char *rbuf;
size_t rbuf_max;
size_t rbuf_offset;
size_t rbuf_len;
struct client_state *client;
int noifmedia;
int errors;
int dead;
u_int16_t index;
};
struct timeout {
struct timeout *next;
time_t when;
void (*func)(void *);
void *what;
};
struct protocol {
struct protocol *next;
int fd;
void (*handler)(struct protocol *);
void *local;
};
#define DEFAULT_HASH_SIZE 97
struct hash_bucket {
struct hash_bucket *next;
unsigned char *name;
int len;
unsigned char *value;
};
struct hash_table {
int hash_count;
struct hash_bucket *buckets[DEFAULT_HASH_SIZE];
};
/* Default path to dhcpd config file. */
#define _PATH_DHCLIENT_CONF "/etc/dhclient.conf"
#define _PATH_DHCLIENT_DB "/var/db/dhclient.leases"
#define DHCPD_LOG_FACILITY LOG_DAEMON
#define MAX_TIME 0x7fffffff
#define MIN_TIME 0
/* External definitions... */
/* options.c */
int cons_options(struct packet *, struct dhcp_packet *, int,
struct tree_cache **, int, int, int, u_int8_t *, int);
char *pretty_print_option(unsigned int,
unsigned char *, int, int, int);
void do_packet(struct interface_info *, struct dhcp_packet *,
int, unsigned int, struct iaddr, struct hardware *);
/* errwarn.c */
extern int warnings_occurred;
void error(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
int warning(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
int note(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
int debug(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
int parse_warn(char *, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
/* conflex.c */
extern int lexline, lexchar;
extern char *token_line, *tlname;
extern char comments[4096];
extern int comment_index;
extern int eol_token;
void new_parse(char *);
int next_token(char **, FILE *);
int peek_token(char **, FILE *);
/* parse.c */
void skip_to_semi(FILE *);
int parse_semi(FILE *);
char *parse_string(FILE *);
int parse_ip_addr(FILE *, struct iaddr *);
void parse_hardware_param(FILE *, struct hardware *);
void parse_lease_time(FILE *, time_t *);
unsigned char *parse_numeric_aggregate(FILE *, unsigned char *, int *,
int, int, int);
void convert_num(unsigned char *, char *, int, int);
time_t parse_date(FILE *);
/* tree.c */
pair cons(caddr_t, pair);
/* alloc.c */
struct string_list *new_string_list(size_t size);
struct hash_table *new_hash_table(int);
struct hash_bucket *new_hash_bucket(void);
/* bpf.c */
int if_register_bpf(struct interface_info *);
void if_register_send(struct interface_info *);
void if_register_receive(struct interface_info *);
ssize_t send_packet(struct interface_info *, struct dhcp_packet *, size_t,
struct in_addr, struct sockaddr_in *, struct hardware *);
ssize_t receive_packet(struct interface_info *, unsigned char *, size_t,
struct sockaddr_in *, struct hardware *);
/* dispatch.c */
extern void (*bootp_packet_handler)(struct interface_info *,
struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *);
void discover_interfaces(struct interface_info *);
void reinitialize_interfaces(void);
void dispatch(void);
void got_one(struct protocol *);
void add_timeout(time_t, void (*)(void *), void *);
void cancel_timeout(void (*)(void *), void *);
void add_protocol(char *, int, void (*)(struct protocol *), void *);
void remove_protocol(struct protocol *);
int interface_link_status(char *);
/* hash.c */
struct hash_table *new_hash(void);
void add_hash(struct hash_table *, unsigned char *, int, unsigned char *);
unsigned char *hash_lookup(struct hash_table *, unsigned char *, int);
/* tables.c */
extern struct dhcp_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(void);
/* convert.c */
u_int32_t getULong(unsigned char *);
int32_t getLong(unsigned char *);
u_int16_t getUShort(unsigned char *);
int16_t getShort(unsigned char *);
void putULong(unsigned char *, u_int32_t);
void putLong(unsigned char *, int32_t);
void putUShort(unsigned char *, unsigned int);
void putShort(unsigned char *, int);
/* inet.c */
struct iaddr subnet_number(struct iaddr, struct iaddr);
struct iaddr broadcast_addr(struct iaddr, struct iaddr);
int addr_eq(struct iaddr, struct iaddr);
char *piaddr(struct iaddr);
/* dhclient.c */
extern char *path_dhclient_conf;
extern char *path_dhclient_db;
extern time_t cur_time;
extern int log_priority;
extern int log_perror;
extern struct client_config top_level_config;
void dhcpoffer(struct packet *);
void dhcpack(struct packet *);
void dhcpnak(struct packet *);
void send_discover(void *);
void send_request(void *);
void send_decline(void *);
void state_reboot(void *);
void state_init(void *);
void state_selecting(void *);
void state_requesting(void *);
void state_bound(void *);
void state_panic(void *);
void bind_lease(struct interface_info *);
void make_discover(struct interface_info *, struct client_lease *);
void make_request(struct interface_info *, struct client_lease *);
void make_decline(struct interface_info *, struct client_lease *);
void free_client_lease(struct client_lease *);
void rewrite_client_leases(void);
void write_client_lease(struct interface_info *, struct client_lease *, int);
void priv_script_init(char *, char *);
void priv_script_write_params(char *, struct client_lease *);
int priv_script_go(void);
void script_init(char *, struct string_list *);
void script_write_params(char *, struct client_lease *);
int script_go(void);
void client_envadd(struct client_state *,
const char *, const char *, const char *, ...);
void script_set_env(struct client_state *, const char *, const char *,
const char *);
void script_flush_env(struct client_state *);
int dhcp_option_ev_name(char *, size_t, struct dhcp_option *);
struct client_lease *packet_to_lease(struct packet *);
void go_daemon(void);
void client_location_changed(void);
void bootp(struct packet *);
void dhcp(struct packet *);
/* packet.c */
void assemble_hw_header(struct interface_info *, unsigned char *,
int *, struct hardware *);
void assemble_udp_ip_header(unsigned char *, int *, u_int32_t, u_int32_t,
unsigned int, unsigned char *, int);
ssize_t decode_hw_header(unsigned char *, int, struct hardware *);
ssize_t decode_udp_ip_header(unsigned char *, int, struct sockaddr_in *,
unsigned char *, int);
/* ethernet.c */
void assemble_ethernet_header(struct interface_info *, unsigned char *,
int *, struct hardware *);
ssize_t decode_ethernet_header(struct interface_info *, unsigned char *,
int, struct hardware *);
/* clparse.c */
int read_client_conf(void);
void read_client_leases(void);
void parse_client_statement(FILE *, struct interface_info *,
struct client_config *);
int parse_X(FILE *, u_int8_t *, int);
int parse_option_list(FILE *, u_int8_t *);
void parse_interface_declaration(FILE *, struct client_config *);
struct interface_info *interface_or_dummy(char *);
void make_client_state(struct interface_info *);
void make_client_config(struct interface_info *, struct client_config *);
void parse_client_lease_statement(FILE *, int);
void parse_client_lease_declaration(FILE *, struct client_lease *,
struct interface_info **);
struct dhcp_option *parse_option_decl(FILE *, struct option_data *);
void parse_string_list(FILE *, struct string_list **, int);
void parse_reject_statement(FILE *, struct client_config *);
/* privsep.c */
struct buf *buf_open(size_t);
int buf_add(struct buf *, void *, size_t);
int buf_close(int, struct buf *);
ssize_t buf_read(int, void *, size_t);
void dispatch_imsg(int);
#endif/*DHCPD_H*/

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,7 @@
#ifndef REACTOS_PREDEC_H
#define REACTOS_PREDEC_H
struct iaddr;
struct interface_info;
#endif

View file

@ -0,0 +1,47 @@
/* $OpenBSD: privsep.h,v 1.2 2004/05/04 18:51:18 henning Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
//#include <poll.h>
//#include <pwd.h>
struct buf {
u_char *buf;
size_t size;
size_t wpos;
size_t rpos;
};
enum imsg_code {
IMSG_NONE,
IMSG_SCRIPT_INIT,
IMSG_SCRIPT_WRITE_PARAMS,
IMSG_SCRIPT_GO,
IMSG_SCRIPT_GO_RET
};
struct imsg_hdr {
enum imsg_code code;
size_t len;
};
struct buf *buf_open(size_t);
int buf_add(struct buf *, void *, size_t);
int buf_close(int, struct buf *);
ssize_t buf_read(int sock, void *, size_t);

View file

@ -0,0 +1,55 @@
#ifndef ROSDHCP_H
#define ROSDHCP_H
#include <roscfg.h>
#include <windows.h>
#include <winnt.h>
#include <iprtrmib.h>
#include <iphlpapi.h>
#include <winsock2.h>
#include <stdio.h>
#include <setjmp.h>
#include "stdint.h"
#include "predec.h"
#include "debug.h"
#define IFNAMSIZ MAX_INTERFACE_NAME_LEN
#undef interface /* wine/objbase.h -- Grrr */
#undef IGNORE
#undef ACCEPT
#undef PREFER
#define DHCP_DISCOVER_INTERVAL 15
#define DHCP_REBOOT_TIMEOUT 300
#define DHCP_BACKOFF_MAX 300
#define _PATH_DHCLIENT_PID "\\systemroot\\system32\\drivers\\etc\\dhclient.pid"
typedef void *VOIDPTR;
#define NTOS_MODE_USER
#include <ntos.h>
typedef u_int32_t uintTIME;
#define TIME uintTIME
#include "dhcpd.h"
#define INLINE inline
#define PROTO(x) x
typedef void (*handler_t) PROTO ((struct packet *));
typedef struct _DHCP_ADAPTER {
LIST_ENTRY ListEntry;
MIB_IFROW IfMib;
MIB_IPADDRROW IfAddr;
SOCKADDR Address;
struct interface_info DhclientInfo;
struct client_state DhclientState;
struct client_config DhclientConfig;
struct sockaddr_in ListenAddr;
unsigned int BindStatus;
char recv_buf[1];
} DHCP_ADAPTER, *PDHCP_ADAPTER;
#define random rand
#define srandom srand
#endif/*ROSDHCP_H*/

View file

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

View file

@ -0,0 +1,13 @@
#ifndef REACTOS_STDINT_H
#define REACTOS_STDINT_H
typedef signed char int8_t;
typedef unsigned char u_int8_t;
typedef short int16_t;
typedef unsigned short u_int16_t;
typedef int int32_t;
typedef unsigned int u_int32_t;
typedef char *caddr_t;
#endif

View file

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

View file

@ -0,0 +1,66 @@
/* $OpenBSD: tree.h,v 1.5 2004/05/06 22:29:15 deraadt Exp $ */
/* 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;
struct tree_cache {
unsigned char *value;
int len;
int buf_size;
time_t timeout;
};
struct universe {
char *name;
struct hash_table *hash;
struct dhcp_option *options[256];
};
struct dhcp_option {
char *name;
char *format;
struct universe *universe;
unsigned char code;
};

View file

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

View file

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

View file

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

View file

@ -0,0 +1,237 @@
/* $OpenBSD: privsep.c,v 1.7 2004/05/10 18:34:42 deraadt Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "rosdhcp.h"
#include "dhcpd.h"
#include "privsep.h"
struct buf *
buf_open(size_t len)
{
struct buf *buf;
if ((buf = calloc(1, sizeof(struct buf))) == NULL)
return (NULL);
if ((buf->buf = malloc(len)) == NULL) {
free(buf);
return (NULL);
}
buf->size = len;
return (buf);
}
int
buf_add(struct buf *buf, void *data, size_t len)
{
if (buf->wpos + len > buf->size)
return (-1);
memcpy(buf->buf + buf->wpos, data, len);
buf->wpos += len;
return (0);
}
int
buf_close(int sock, struct buf *buf)
{
ssize_t n;
do {
n = write(sock, buf->buf + buf->rpos, buf->size - buf->rpos);
if (n != -1)
buf->rpos += n;
if (n == 0) { /* connection closed */
errno = 0;
return (-1);
}
} while (n == -1 && (errno == EAGAIN || errno == EINTR));
if (buf->rpos < buf->size)
error("short write: wanted %lu got %ld bytes",
(unsigned long)buf->size, (long)buf->rpos);
free(buf->buf);
free(buf);
return (n);
}
ssize_t
buf_read(int sock, void *buf, size_t nbytes)
{
ssize_t n, r = 0;
char *p = buf;
do {
n = read(sock, p, nbytes);
if (n == 0)
error("connection closed");
if (n != -1) {
r += n;
p += n;
nbytes -= n;
}
} while (n == -1 && (errno == EINTR || errno == EAGAIN));
if (n == -1)
error("buf_read: %m");
if (r < nbytes)
error("short read: wanted %lu got %ld bytes",
(unsigned long)nbytes, (long)r);
return (r);
}
void
dispatch_imsg(int fd)
{
struct imsg_hdr hdr;
char *medium, *reason, *filename,
*servername, *prefix;
size_t medium_len, reason_len, filename_len,
servername_len, prefix_len, totlen;
struct client_lease lease;
int ret, i, optlen;
struct buf *buf;
buf_read(fd, &hdr, sizeof(hdr));
switch (hdr.code) {
case IMSG_SCRIPT_INIT:
if (hdr.len < sizeof(hdr) + sizeof(size_t))
error("corrupted message received");
buf_read(fd, &medium_len, sizeof(medium_len));
if (hdr.len < medium_len + sizeof(size_t) + sizeof(hdr)
+ sizeof(size_t) || medium_len == SIZE_T_MAX)
error("corrupted message received");
if (medium_len > 0) {
if ((medium = calloc(1, medium_len + 1)) == NULL)
error("%m");
buf_read(fd, medium, medium_len);
} else
medium = NULL;
buf_read(fd, &reason_len, sizeof(reason_len));
if (hdr.len < medium_len + reason_len + sizeof(hdr) ||
reason_len == SIZE_T_MAX)
error("corrupted message received");
if (reason_len > 0) {
if ((reason = calloc(1, reason_len + 1)) == NULL)
error("%m");
buf_read(fd, reason, reason_len);
} else
reason = NULL;
// priv_script_init(reason, medium);
free(reason);
free(medium);
break;
case IMSG_SCRIPT_WRITE_PARAMS:
//bzero(&lease, sizeof lease);
memset(&lease, 0, sizeof(lease));
totlen = sizeof(hdr) + sizeof(lease) + sizeof(size_t);
if (hdr.len < totlen)
error("corrupted message received");
buf_read(fd, &lease, sizeof(lease));
buf_read(fd, &filename_len, sizeof(filename_len));
totlen += filename_len + sizeof(size_t);
if (hdr.len < totlen || filename_len == SIZE_T_MAX)
error("corrupted message received");
if (filename_len > 0) {
if ((filename = calloc(1, filename_len + 1)) == NULL)
error("%m");
buf_read(fd, filename, filename_len);
} else
filename = NULL;
buf_read(fd, &servername_len, sizeof(servername_len));
totlen += servername_len + sizeof(size_t);
if (hdr.len < totlen || servername_len == SIZE_T_MAX)
error("corrupted message received");
if (servername_len > 0) {
if ((servername =
calloc(1, servername_len + 1)) == NULL)
error("%m");
buf_read(fd, servername, servername_len);
} else
servername = NULL;
buf_read(fd, &prefix_len, sizeof(prefix_len));
totlen += prefix_len;
if (hdr.len < totlen || prefix_len == SIZE_T_MAX)
error("corrupted message received");
if (prefix_len > 0) {
if ((prefix = calloc(1, prefix_len + 1)) == NULL)
error("%m");
buf_read(fd, prefix, prefix_len);
} else
prefix = NULL;
for (i = 0; i < 256; i++) {
totlen += sizeof(optlen);
if (hdr.len < totlen)
error("corrupted message received");
buf_read(fd, &optlen, sizeof(optlen));
lease.options[i].data = NULL;
lease.options[i].len = optlen;
if (optlen > 0) {
totlen += optlen;
if (hdr.len < totlen || optlen == SIZE_T_MAX)
error("corrupted message received");
lease.options[i].data =
calloc(1, optlen + 1);
if (lease.options[i].data == NULL)
error("%m");
buf_read(fd, lease.options[i].data, optlen);
}
}
lease.server_name = servername;
lease.filename = filename;
// priv_script_write_params(prefix, &lease);
free(servername);
free(filename);
free(prefix);
for (i = 0; i < 256; i++)
if (lease.options[i].len > 0)
free(lease.options[i].data);
break;
case IMSG_SCRIPT_GO:
if (hdr.len != sizeof(hdr))
error("corrupted message received");
// ret = priv_script_go();
hdr.code = IMSG_SCRIPT_GO_RET;
hdr.len = sizeof(struct imsg_hdr) + sizeof(int);
if ((buf = buf_open(hdr.len)) == NULL)
error("buf_open: %m");
if (buf_add(buf, &hdr, sizeof(hdr)))
error("buf_add: %m");
if (buf_add(buf, &ret, sizeof(ret)))
error("buf_add: %m");
if (buf_close(fd, buf) == -1)
error("buf_close: %m");
break;
default:
error("received unknown message, code %d", hdr.code);
}
}

View file

@ -0,0 +1,24 @@
#include "rosdhcp.h"
SOCKET ServerSocket;
void SocketInit() {
ServerSocket = socket( AF_INET, SOCK_DGRAM, 0 );
}
ssize_t send_packet( struct interface_info *ip,
struct dhcp_packet *p,
size_t size,
struct in_addr addr,
struct sockaddr_in *broadcast,
struct hardware *hardware ) {
return 0;
}
ssize_t receive_packet(struct interface_info *ip,
unsigned char *packet_data,
size_t packet_len,
struct sockaddr_in *dest,
struct hardware *hardware ) {
return 0;
}

View file

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

View file

@ -0,0 +1,2 @@
#include "rosdhcp.h"

View file

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

View file

@ -0,0 +1,106 @@
#include <stdarg.h>
#include "rosdhcp.h"
char *piaddr( struct iaddr addr ) {
struct sockaddr_in *sa = (struct sockaddr_in *)addr.iabuf;
return inet_ntoa( sa->sin_addr );
}
int note( char *format, ... ) {
va_list arg_begin;
va_start( arg_begin, format );
char buf[0x100];
int ret;
ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
DbgPrint("NOTE: %s\n", buf);
return ret;
}
int debug( char *format, ... ) {
va_list arg_begin;
va_start( arg_begin, format );
char buf[0x100];
int ret;
ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
DbgPrint("DEBUG: %s\n", buf);
return ret;
}
int warn( char *format, ... ) {
va_list arg_begin;
va_start( arg_begin, format );
char buf[0x100];
int ret;
ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
DbgPrint("WARN: %s\n", buf);
return ret;
}
int warning( char *format, ... ) {
va_list arg_begin;
va_start( arg_begin, format );
char buf[0x100];
int ret;
ret = vsnprintf( buf, sizeof(buf), format, arg_begin );
DbgPrint("WARNING: %s\n", buf);
return ret;
}
void error( char *format, ... ) {
va_list arg_begin;
va_start( arg_begin, format );
char buf[0x100];
vsnprintf( buf, sizeof(buf), format, arg_begin );
DbgPrint("ERROR: %s\n", buf);
}
int16_t getShort( unsigned char *data ) {
return 0;
}
u_int16_t getUShort( unsigned char *data ) {
return 0;
}
int32_t getLong( unsigned char *data ) {
return 0;
}
u_int32_t getULong( unsigned char *data ) {
return 0;
}
int addr_eq( struct iaddr a, struct iaddr b ) {
return a.len == b.len && !memcmp( a.iabuf, b.iabuf, a.len );
}
void *dmalloc( int size, char *name ) { return malloc( size ); }
void dfree( void *v, char *name ) { free( v ); }
int read_client_conf(void) {
return 0;
}
struct iaddr broadcast_addr( struct iaddr addr, struct iaddr mask ) {
struct iaddr bcast = { 0 };
return bcast;
}
struct iaddr subnet_number( struct iaddr addr, struct iaddr mask ) {
struct iaddr bcast = { 0 };
return bcast;
}