DHCPCSVC]

- Move code from dhcp to dhcpcsvc
- Export ServiceMain from dhcpcsvc
- Now our DHCP service is compatible with the Windows architecture
[DHCP]
- Remove dhcp from build
[IPHLPAPI]
- Use dhcpcsvc APIs to control the DHCP service
- Add a missing DhcpCApiInitialize
- Fix include path in the rbuild file
[BOOTDATA]
- Add DHCP to the service list to be loaded by svchost in the netsvcs group
- Add the correct registry keys in the DHCP service key for loading by svchost
- Remove dhcp.exe from bootcd

- Part 3 of 3

svn path=/trunk/; revision=47288
This commit is contained in:
Cameron Gutman 2010-05-21 06:08:15 +00:00
parent 83add143de
commit 2b3f32398d
31 changed files with 6616 additions and 91 deletions

View file

@ -4,9 +4,6 @@
<directory name="audiosrv">
<xi:include href="audiosrv/audiosrv.rbuild" />
</directory>
<directory name="dhcp">
<xi:include href="dhcp/dhcp.rbuild" />
</directory>
<directory name="eventlog">
<xi:include href="eventlog/eventlog.rbuild" />
</directory>

View file

@ -1128,6 +1128,6 @@ HKLM,"SOFTWARE\Microsoft\Windows\CurrentVersion\Controls Folder\Device\shellex\P
; SvcHost services
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost",,0x00000012
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost", "netsvcs",0x00010000,""
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost", "netsvcs",0x00010000,"DHCP"
; EOF

View file

@ -1264,6 +1264,6 @@ HKLM,"SOFTWARE\Microsoft\Ole","EnableRemoteConnect",0x00000000,"N"
; SvcHost services
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost",,0x00000012
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost", "netsvcs",0x00010000,""
HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost", "netsvcs",0x00010000,"DHCP"
; EOF

View file

@ -1037,12 +1037,13 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Disk","Type",0x00010001,0x00000001
; DHCP client service
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","DisplayName",0x00000000,"DHCP Client"
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Description",0x00000000,"Attempts to obtain network settings automatically from an available DHCP server"
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","ErrorControl",0x00010001,0x00000000
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Group",0x00000000,"Network"
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","ImagePath",0x00020000,"%SystemRoot%\system32\dhcp.exe"
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","ErrorControl",0x00010001,0x00000001
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Group",0x00000000,"TDI"
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","ImagePath",0x00020000,"%SystemRoot%\system32\svchost.exe -k netsvcs"
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","ObjectName",0x00000000,"LocalSystem"
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Start",0x00010001,0x00000002
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Type",0x00010001,0x00000010
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP","Type",0x00010001,0x00000020
HKLM,"SYSTEM\CurrentControlSet\Services\DHCP\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\dhcpcsvc.dll"
; Event logging service
HKLM,"SYSTEM\CurrentControlSet\Services\EventLog",,0x00000010

View file

@ -90,7 +90,6 @@ base\applications\wordpad\wordpad.exe 1
base\applications\write\write.exe 1
base\services\audiosrv\audiosrv.exe 1
base\services\dhcp\dhcp.exe 1
base\services\eventlog\eventlog.exe 1
base\services\rpcss\rpcss.exe 1
base\services\spoolsv\spoolsv.exe 1

View file

@ -0,0 +1,446 @@
#include "rosdhcp.h"
static SOCKET DhcpSocket = INVALID_SOCKET;
static LIST_ENTRY AdapterList;
static WSADATA wsd;
PCHAR *GetSubkeyNames( PCHAR MainKeyName, PCHAR Append ) {
int i = 0;
DWORD Error;
HKEY MainKey;
PCHAR *Out, OutKeyName;
DWORD CharTotal = 0, AppendLen = 1 + strlen(Append);
DWORD MaxSubKeyLen = 0, MaxSubKeys = 0;
Error = RegOpenKey( HKEY_LOCAL_MACHINE, MainKeyName, &MainKey );
if( Error ) return NULL;
Error = RegQueryInfoKey
( MainKey,
NULL, NULL, NULL,
&MaxSubKeys, &MaxSubKeyLen,
NULL, NULL, NULL, NULL, NULL, NULL );
DH_DbgPrint(MID_TRACE,("MaxSubKeys: %d, MaxSubKeyLen %d\n",
MaxSubKeys, MaxSubKeyLen));
CharTotal = (sizeof(PCHAR) + MaxSubKeyLen + AppendLen) * (MaxSubKeys + 1);
DH_DbgPrint(MID_TRACE,("AppendLen: %d, CharTotal: %d\n",
AppendLen, CharTotal));
Out = (CHAR**) malloc( CharTotal );
OutKeyName = ((PCHAR)&Out[MaxSubKeys+1]);
if( !Out ) { RegCloseKey( MainKey ); return NULL; }
i = 0;
do {
Out[i] = OutKeyName;
Error = RegEnumKey( MainKey, i, OutKeyName, MaxSubKeyLen );
if( !Error ) {
strcat( OutKeyName, Append );
DH_DbgPrint(MID_TRACE,("[%d]: %s\n", i, OutKeyName));
OutKeyName += strlen(OutKeyName) + 1;
i++;
} else Out[i] = 0;
} while( Error == ERROR_SUCCESS );
RegCloseKey( MainKey );
return Out;
}
PCHAR RegReadString( HKEY Root, PCHAR Subkey, PCHAR Value ) {
PCHAR SubOut = NULL;
DWORD SubOutLen = 0, Error = 0;
HKEY ValueKey = NULL;
DH_DbgPrint(MID_TRACE,("Looking in %x:%s:%s\n", Root, Subkey, Value ));
if( Subkey && strlen(Subkey) ) {
if( RegOpenKey( Root, Subkey, &ValueKey ) != ERROR_SUCCESS )
goto regerror;
} else ValueKey = Root;
DH_DbgPrint(MID_TRACE,("Got Key %x\n", ValueKey));
if( (Error = RegQueryValueEx( ValueKey, Value, NULL, NULL,
(LPBYTE)SubOut, &SubOutLen )) != ERROR_SUCCESS )
goto regerror;
DH_DbgPrint(MID_TRACE,("Value %s has size %d\n", Value, SubOutLen));
if( !(SubOut = (CHAR*) malloc(SubOutLen)) )
goto regerror;
if( (Error = RegQueryValueEx( ValueKey, Value, NULL, NULL,
(LPBYTE)SubOut, &SubOutLen )) != ERROR_SUCCESS )
goto regerror;
DH_DbgPrint(MID_TRACE,("Value %s is %s\n", Value, SubOut));
goto cleanup;
regerror:
if( SubOut ) { free( SubOut ); SubOut = NULL; }
cleanup:
if( ValueKey && ValueKey != Root ) {
DH_DbgPrint(MID_TRACE,("Closing key %x\n", ValueKey));
RegCloseKey( ValueKey );
}
DH_DbgPrint(MID_TRACE,("Returning %x with error %d\n", SubOut, Error));
return SubOut;
}
HKEY FindAdapterKey( PDHCP_ADAPTER Adapter ) {
int i = 0;
PCHAR EnumKeyName =
"SYSTEM\\CurrentControlSet\\Control\\Class\\"
"{4D36E972-E325-11CE-BFC1-08002BE10318}";
PCHAR TargetKeyNameStart =
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
PCHAR TargetKeyName = NULL;
PCHAR *EnumKeysLinkage = GetSubkeyNames( EnumKeyName, "\\Linkage" );
PCHAR *EnumKeysTop = GetSubkeyNames( EnumKeyName, "" );
PCHAR RootDevice = NULL;
HKEY EnumKey, OutKey = NULL;
DWORD Error = ERROR_SUCCESS;
if( !EnumKeysLinkage || !EnumKeysTop ) goto cleanup;
Error = RegOpenKey( HKEY_LOCAL_MACHINE, EnumKeyName, &EnumKey );
if( Error ) goto cleanup;
for( i = 0; EnumKeysLinkage[i]; i++ ) {
RootDevice = RegReadString
( EnumKey, EnumKeysLinkage[i], "RootDevice" );
if( RootDevice &&
!strcmp( RootDevice, Adapter->DhclientInfo.name ) ) {
TargetKeyName =
(CHAR*) malloc( strlen( TargetKeyNameStart ) +
strlen( RootDevice ) + 1);
if( !TargetKeyName ) goto cleanup;
sprintf( TargetKeyName, "%s%s",
TargetKeyNameStart, RootDevice );
Error = RegCreateKeyExA( HKEY_LOCAL_MACHINE, TargetKeyName, 0, NULL, 0, KEY_READ, NULL, &OutKey, NULL );
break;
} else {
free( RootDevice ); RootDevice = 0;
}
}
cleanup:
if( RootDevice ) free( RootDevice );
if( EnumKeysLinkage ) free( EnumKeysLinkage );
if( EnumKeysTop ) free( EnumKeysTop );
if( TargetKeyName ) free( TargetKeyName );
return OutKey;
}
BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) {
HKEY AdapterKey = NULL;
PCHAR IPAddress = NULL, Netmask = NULL, DefaultGateway = NULL;
NTSTATUS Status = STATUS_SUCCESS;
DWORD Error = ERROR_SUCCESS;
Adapter->DhclientState.config = &Adapter->DhclientConfig;
strncpy(Adapter->DhclientInfo.name, (char*)Adapter->IfMib.bDescr,
sizeof(Adapter->DhclientInfo.name));
AdapterKey = FindAdapterKey( Adapter );
if( AdapterKey )
IPAddress = RegReadString( AdapterKey, NULL, "IPAddress" );
if( IPAddress && strcmp( IPAddress, "0.0.0.0" ) ) {
/* Non-automatic case */
DH_DbgPrint
(MID_TRACE,("Adapter Name: [%s] (Bind Status %x) (static %s)\n",
Adapter->DhclientInfo.name,
Adapter->BindStatus,
IPAddress));
Adapter->DhclientState.state = S_STATIC;
Netmask = RegReadString( AdapterKey, NULL, "Subnetmask" );
Status = AddIPAddress( inet_addr( IPAddress ),
inet_addr( Netmask ? Netmask : "255.255.255.0" ),
Adapter->IfMib.dwIndex,
&Adapter->NteContext,
&Adapter->NteInstance );
DefaultGateway = RegReadString( AdapterKey, NULL, "DefaultGateway" );
if( DefaultGateway ) {
Adapter->RouterMib.dwForwardDest = 0;
Adapter->RouterMib.dwForwardMask = 0;
Adapter->RouterMib.dwForwardMetric1 = 1;
Adapter->RouterMib.dwForwardIfIndex = Adapter->IfMib.dwIndex;
Adapter->RouterMib.dwForwardNextHop = inet_addr(DefaultGateway);
Error = CreateIpForwardEntry( &Adapter->RouterMib );
if( Error )
warning("Failed to set default gateway %s: %ld\n",
DefaultGateway, Error);
}
if( DefaultGateway ) free( DefaultGateway );
if( Netmask ) free( Netmask );
} else {
/* Automatic case */
DH_DbgPrint
(MID_TRACE,("Adapter Name: [%s] (Bind Status %x) (dynamic)\n",
Adapter->DhclientInfo.name,
Adapter->BindStatus));
Adapter->DhclientInfo.client->state = S_INIT;
}
if( IPAddress ) free( IPAddress );
return TRUE;
}
void AdapterInit() {
WSAStartup(0x0101,&wsd);
InitializeListHead( &AdapterList );
}
int
InterfaceConnected(MIB_IFROW IfEntry)
{
if (IfEntry.dwOperStatus == IF_OPER_STATUS_CONNECTED ||
IfEntry.dwOperStatus == IF_OPER_STATUS_OPERATIONAL)
return 1;
DH_DbgPrint(MID_TRACE,("Interface %d is down\n", IfEntry.dwIndex));
return 0;
}
/*
* XXX Figure out the way to bind a specific adapter to a socket.
*/
BOOLEAN AdapterDiscover() {
PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
DWORD Error, Size = sizeof(MIB_IFTABLE);
PDHCP_ADAPTER Adapter = NULL;
struct interface_info *ifi = NULL;
int i;
BOOLEAN ret = TRUE;
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 = (PMIB_IFTABLE) malloc( Size );
}
if( Error != NO_ERROR ) {
ret = FALSE;
goto term;
}
DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));
for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
Table->table[i].dwIndex));
if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen)))
{
/* This is an existing adapter */
if (InterfaceConnected(Table->table[i])) {
/* We're still active so we stay in the list */
ifi = &Adapter->DhclientInfo;
} else {
/* We've lost our link so out we go */
RemoveEntryList(&Adapter->ListEntry);
free(Adapter);
}
continue;
}
Adapter = (DHCP_ADAPTER*) calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );
if( Adapter && Table->table[i].dwType == MIB_IF_TYPE_ETHERNET && InterfaceConnected(Table->table[i])) {
memcpy( &Adapter->IfMib, &Table->table[i],
sizeof(Adapter->IfMib) );
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;
memcpy(Adapter->DhclientInfo.hw_address.haddr,
Adapter->IfMib.bPhysAddr,
Adapter->IfMib.dwPhysAddrLen);
Adapter->DhclientInfo.hw_address.hlen =
Adapter->IfMib.dwPhysAddrLen;
/* I'm not sure where else to set this, but
some DHCP servers won't take a zero.
We checked the hardware type earlier in
the if statement. */
Adapter->DhclientInfo.hw_address.htype =
HTYPE_ETHER;
if( DhcpSocket == INVALID_SOCKET ) {
DhcpSocket =
Adapter->DhclientInfo.rfdesc =
Adapter->DhclientInfo.wfdesc =
socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
if (DhcpSocket != INVALID_SOCKET) {
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();
} else {
error("socket() failed: %d\n", WSAGetLastError());
}
} else {
Adapter->DhclientInfo.rfdesc =
Adapter->DhclientInfo.wfdesc = DhcpSocket;
}
Adapter->DhclientConfig.timeout = DHCP_PANIC_TIMEOUT;
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;
if( PrepareAdapterForService( Adapter ) ) {
Adapter->DhclientInfo.next = ifi;
ifi = &Adapter->DhclientInfo;
read_client_conf(&Adapter->DhclientInfo);
if (Adapter->DhclientInfo.client->state == S_INIT)
{
add_protocol(Adapter->DhclientInfo.name,
Adapter->DhclientInfo.rfdesc,
got_one, &Adapter->DhclientInfo);
state_init(&Adapter->DhclientInfo);
}
InsertTailList( &AdapterList, &Adapter->ListEntry );
} else { free( Adapter ); Adapter = 0; }
} else { free( Adapter ); Adapter = 0; }
if( !Adapter )
DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n",
Table->table[i].dwIndex));
}
DH_DbgPrint(MID_TRACE,("done with AdapterInit\n"));
term:
if( Table ) free( Table );
return ret;
}
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 AdapterFindInfo( struct interface_info *ip ) {
PDHCP_ADAPTER Adapter;
PLIST_ENTRY ListEntry;
for( ListEntry = AdapterList.Flink;
ListEntry != &AdapterList;
ListEntry = ListEntry->Flink ) {
Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
if( ip == &Adapter->DhclientInfo ) return Adapter;
}
return NULL;
}
PDHCP_ADAPTER AdapterFindByHardwareAddress( u_int8_t haddr[16], u_int8_t hlen ) {
PDHCP_ADAPTER Adapter;
PLIST_ENTRY ListEntry;
for(ListEntry = AdapterList.Flink;
ListEntry != &AdapterList;
ListEntry = ListEntry->Flink) {
Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
if (Adapter->DhclientInfo.hw_address.hlen == hlen &&
!memcmp(Adapter->DhclientInfo.hw_address.haddr,
haddr,
hlen)) 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,93 @@
/* $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
dfree(void *ptr, char *name)
{
if (!ptr) {
warning("dfree %s: free on null pointer.", name);
return;
}
free(ptr);
}
void
free_hash_bucket(struct hash_bucket *ptr, char *name)
{
dfree(ptr, name);
}

View file

@ -0,0 +1,201 @@
/* $Id: $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: subsys/system/dhcp/api.c
* PURPOSE: DHCP client api handlers
* PROGRAMMER: arty
*/
#include "rosdhcp.h"
#include <winsock2.h>
#include <iphlpapi.h>
#define NDEBUG
#include <reactos/debug.h>
static CRITICAL_SECTION ApiCriticalSection;
VOID ApiInit() {
InitializeCriticalSection( &ApiCriticalSection );
}
VOID ApiLock() {
EnterCriticalSection( &ApiCriticalSection );
}
VOID ApiUnlock() {
LeaveCriticalSection( &ApiCriticalSection );
}
VOID ApiFree() {
DeleteCriticalSection( &ApiCriticalSection );
}
/* This represents the service portion of the DHCP client API */
DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
Reply.Reply = Adapter ? 1 : 0;
if( Adapter ) {
add_protocol( Adapter->DhclientInfo.name,
Adapter->DhclientInfo.rfdesc, got_one,
&Adapter->DhclientInfo );
Adapter->DhclientInfo.client->state = S_INIT;
state_reboot(&Adapter->DhclientInfo);
}
ApiUnlock();
return Send( &Reply );
}
DWORD DSQueryHWInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
Reply.Reply = Adapter ? 1 : 0;
if (Adapter) {
Reply.QueryHWInfo.AdapterIndex = Req->AdapterIndex;
Reply.QueryHWInfo.MediaType = Adapter->IfMib.dwType;
Reply.QueryHWInfo.Mtu = Adapter->IfMib.dwMtu;
Reply.QueryHWInfo.Speed = Adapter->IfMib.dwSpeed;
}
ApiUnlock();
return Send( &Reply );
}
DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
struct protocol* proto;
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
Reply.Reply = Adapter ? 1 : 0;
if( Adapter ) {
if (Adapter->NteContext)
DeleteIPAddress( Adapter->NteContext );
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto)
remove_protocol(proto);
}
ApiUnlock();
return Send( &Reply );
}
DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
if( !Adapter || Adapter->DhclientState.state == S_STATIC ) {
Reply.Reply = 0;
ApiUnlock();
return Send( &Reply );
}
Reply.Reply = 1;
add_protocol( Adapter->DhclientInfo.name,
Adapter->DhclientInfo.rfdesc, got_one,
&Adapter->DhclientInfo );
Adapter->DhclientInfo.client->state = S_INIT;
state_reboot(&Adapter->DhclientInfo);
ApiUnlock();
return Send( &Reply );
}
DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
NTSTATUS Status;
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
struct protocol* proto;
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
Reply.Reply = Adapter ? 1 : 0;
if( Adapter ) {
if (Adapter->NteContext)
DeleteIPAddress( Adapter->NteContext );
Adapter->DhclientState.state = S_STATIC;
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto)
remove_protocol(proto);
Status = AddIPAddress( Req->Body.StaticRefreshParams.IPAddress,
Req->Body.StaticRefreshParams.Netmask,
Req->AdapterIndex,
&Adapter->NteContext,
&Adapter->NteInstance );
Reply.Reply = NT_SUCCESS(Status);
}
ApiUnlock();
return Send( &Reply );
}
DWORD DSGetAdapterInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
Reply.Reply = Adapter ? 1 : 0;
if( Adapter ) {
Reply.GetAdapterInfo.DhcpEnabled = (S_STATIC != Adapter->DhclientState.state);
if (S_BOUND == Adapter->DhclientState.state) {
if (sizeof(Reply.GetAdapterInfo.DhcpServer) ==
Adapter->DhclientState.active->serveraddress.len) {
memcpy(&Reply.GetAdapterInfo.DhcpServer,
Adapter->DhclientState.active->serveraddress.iabuf,
Adapter->DhclientState.active->serveraddress.len);
} else {
DPRINT1("Unexpected server address len %d\n",
Adapter->DhclientState.active->serveraddress.len);
Reply.GetAdapterInfo.DhcpServer = htonl(INADDR_NONE);
}
Reply.GetAdapterInfo.LeaseObtained = Adapter->DhclientState.active->obtained;
Reply.GetAdapterInfo.LeaseExpires = Adapter->DhclientState.active->expiry;
} else {
Reply.GetAdapterInfo.DhcpServer = htonl(INADDR_NONE);
Reply.GetAdapterInfo.LeaseObtained = 0;
Reply.GetAdapterInfo.LeaseExpires = 0;
}
}
ApiUnlock();
return Send( &Reply );
}

View file

@ -0,0 +1,67 @@
#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)
/* inet_addr code from ROS, slightly modified. */
{
ULONG Octets[4] = {0,0,0,0};
ULONG i = 0;
if(!cp)
return 0;
while(*cp)
{
CHAR c = *cp;
cp++;
if(c == '.')
{
i++;
continue;
}
if(c < '0' || c > '9')
return 0;
Octets[i] *= 10;
Octets[i] += (c - '0');
if(Octets[i] > 255)
return 0;
}
inp->S_un.S_addr = (Octets[3] << 24) + (Octets[2] << 16) + (Octets[1] << 8) + Octets[0];
return 1;
}

File diff suppressed because it is too large Load diff

View file

@ -6,22 +6,63 @@
* COPYRIGHT: Copyright 2005 Art Yerkes <ayerkes@speakeasy.net>
*/
#include <winsock2.h>
#include <dhcpcsdk.h>
#include <time.h>
#include <dhcp/rosdhcp_public.h>
#include <rosdhcp.h>
#define NDEBUG
#include <debug.h>
#define DHCP_TIMEOUT 1000
static HANDLE PipeHandle = INVALID_HANDLE_VALUE;
DWORD APIENTRY DhcpCApiInitialize(LPDWORD Version) {
*Version = 2;
return 0;
DWORD PipeMode;
/* Wait for the pipe to be available */
if (WaitNamedPipeW(DHCP_PIPE_NAME, NMPWAIT_USE_DEFAULT_WAIT))
{
/* It's available, let's try to open it */
PipeHandle = CreateFileW(DHCP_PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
/* Check if we succeeded in opening the pipe */
if (PipeHandle == INVALID_HANDLE_VALUE)
{
/* We didn't */
return GetLastError();
}
else
{
/* Change the pipe into message mode */
PipeMode = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(PipeHandle, &PipeMode, NULL, NULL))
{
/* Mode change failed */
CloseHandle(PipeHandle);
PipeHandle = INVALID_HANDLE_VALUE;
return GetLastError();
}
else
{
/* We're good to go */
*Version = 2;
return NO_ERROR;
}
}
}
else
{
/* No good, we failed */
return GetLastError();
}
}
VOID APIENTRY DhcpCApiCleanup() {
CloseHandle(PipeHandle);
PipeHandle = INVALID_HANDLE_VALUE;
}
DWORD APIENTRY DhcpQueryHWInfo( DWORD AdapterIndex,
@ -33,12 +74,20 @@ DWORD APIENTRY DhcpQueryHWInfo( DWORD AdapterIndex,
DWORD BytesRead;
BOOL Result;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqQueryHWInfo;
Req.AdapterIndex = AdapterIndex;
Result = CallNamedPipeW
( DHCP_PIPE_NAME, &Req, sizeof(Req), &Reply, sizeof(Reply),
&BytesRead, DHCP_TIMEOUT );
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
{
/* Pipe transaction failed */
return 0;
}
if( !Reply.Reply ) return 0;
else {
@ -55,12 +104,20 @@ DWORD APIENTRY DhcpLeaseIpAddress( DWORD AdapterIndex ) {
DWORD BytesRead;
BOOL Result;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqLeaseIpAddress;
Req.AdapterIndex = AdapterIndex;
Result = CallNamedPipeW
( DHCP_PIPE_NAME, &Req, sizeof(Req), &Reply, sizeof(Reply),
&BytesRead, DHCP_TIMEOUT );
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
{
/* Pipe transaction failed */
return 0;
}
return Reply.Reply;
}
@ -71,12 +128,20 @@ DWORD APIENTRY DhcpReleaseIpAddressLease( DWORD AdapterIndex ) {
DWORD BytesRead;
BOOL Result;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqReleaseIpAddress;
Req.AdapterIndex = AdapterIndex;
Result = CallNamedPipeW
( DHCP_PIPE_NAME, &Req, sizeof(Req), &Reply, sizeof(Reply),
&BytesRead, DHCP_TIMEOUT );
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
{
/* Pipe transaction failed */
return 0;
}
return Reply.Reply;
}
@ -87,12 +152,20 @@ DWORD APIENTRY DhcpRenewIpAddressLease( DWORD AdapterIndex ) {
DWORD BytesRead;
BOOL Result;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqRenewIpAddress;
Req.AdapterIndex = AdapterIndex;
Result = CallNamedPipeW
( DHCP_PIPE_NAME, &Req, sizeof(Req), &Reply, sizeof(Reply),
&BytesRead, DHCP_TIMEOUT );
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
{
/* Pipe transaction failed */
return 0;
}
return Reply.Reply;
}
@ -105,14 +178,22 @@ DWORD APIENTRY DhcpStaticRefreshParams( DWORD AdapterIndex,
DWORD BytesRead;
BOOL Result;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqStaticRefreshParams;
Req.AdapterIndex = AdapterIndex;
Req.Body.StaticRefreshParams.IPAddress = Address;
Req.Body.StaticRefreshParams.Netmask = Netmask;
Result = CallNamedPipeW
( DHCP_PIPE_NAME, &Req, sizeof(Req), &Reply, sizeof(Reply),
&BytesRead, DHCP_TIMEOUT );
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
{
/* Pipe transaction failed */
return 0;
}
return Reply.Reply;
}
@ -153,7 +234,7 @@ DhcpNotifyConfigChange(LPWSTR ServerName,
DWORD SubnetMask,
int DhcpAction)
{
DPRINT1("DhcpNotifyConfigChange not implemented yet\n");
DbgPrint("DHCPCSVC: DhcpNotifyConfigChange not implemented yet\n");
return 0;
}
@ -192,12 +273,15 @@ DWORD APIENTRY DhcpRosGetAdapterInfo( DWORD AdapterIndex,
DWORD BytesRead;
BOOL Result;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqGetAdapterInfo;
Req.AdapterIndex = AdapterIndex;
Result = CallNamedPipeW
( DHCP_PIPE_NAME, &Req, sizeof(Req), &Reply, sizeof(Reply),
&BytesRead, DHCP_TIMEOUT );
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if ( 0 != Result && 0 != Reply.Reply ) {
*DhcpEnabled = Reply.GetAdapterInfo.DhcpEnabled;

View file

@ -2,8 +2,26 @@
<importlibrary definition="dhcpcsvc.spec" />
<include base="dhcpcsvc">include</include>
<library>ntdll</library>
<library>msvcrt</library>
<library>ws2_32</library>
<library>iphlpapi</library>
<library>advapi32</library>
<library>oldnames</library>
<file>adapter.c</file>
<file>alloc.c</file>
<file>api.c</file>
<file>compat.c</file>
<file>dhclient.c</file>
<file>dhcpcsvc.c</file>
<file>dhcpcsvc.rc</file>
<file>dispatch.c</file>
<file>hash.c</file>
<file>options.c</file>
<file>pipe.c</file>
<file>socket.c</file>
<file>tables.c</file>
<file>util.c</file>
<directory name="include">
<pch>rosdhcp.h</pch>
</directory>
</module>

View file

@ -43,5 +43,4 @@
@ stub McastRenewAddress
@ stub McastRequestAddress
@ stdcall DhcpRosGetAdapterInfo(long ptr ptr ptr ptr)
# The Windows DHCP client service is implemented in the DLL too
#@ stub ServiceMain
@ stdcall ServiceMain(long ptr)

View file

@ -0,0 +1,354 @@
/* $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;
void (*bootp_packet_handler)(struct interface_info *,
struct dhcp_packet *, int, unsigned int,
struct iaddr, struct hardware *);
/*
* 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, to_msec, err;
struct protocol *l;
fd_set fds;
time_t howlong, cur_time;
struct timeval timeval;
if (!AdapterDiscover())
return;
ApiLock();
do {
/*
* Call any expired timeouts, and then if there's still
* a timeout registered, time out the select call then.
*/
time(&cur_time);
if (timeouts) {
struct timeout *t;
if (timeouts->when <= cur_time) {
t = timeouts;
timeouts = timeouts->next;
(*(t->func))(t->what);
t->next = free_timeouts;
free_timeouts = t;
continue;
}
/*
* 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 = 5000;
/* Set up the descriptors to be polled. */
FD_ZERO(&fds);
for (l = protocols; l; l = l->next)
FD_SET(l->fd, &fds);
/* Wait for a packet or a timeout... XXX */
timeval.tv_sec = to_msec / 1000;
timeval.tv_usec = to_msec % 1000;
ApiUnlock();
if (protocols)
count = select(0, &fds, NULL, NULL, &timeval);
else {
Sleep(to_msec);
count = 0;
}
ApiLock();
DH_DbgPrint(MID_TRACE,("Select: %d\n", count));
/* Not likely to be transitory... */
if (count == SOCKET_ERROR) {
err = WSAGetLastError();
error("poll: %d", err);
break;
}
for (l = protocols; l; l = l->next) {
struct interface_info *ip;
ip = l->local;
if (FD_ISSET(l->fd, &fds)) {
if (ip && (l->handler != got_one ||
!ip->dead)) {
DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
(*(l->handler))(l);
}
}
}
} while (1);
ApiUnlock();
}
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;
PDHCP_ADAPTER adapter;
if ((result = receive_packet(ip, u.packbuf, sizeof(u), &from,
&hfrom)) == -1) {
warning("receive_packet failed on %s: %d", ip->name,
WSAGetLastError());
ip->errors++;
if (ip->errors > 20) {
/* our interface has gone away. */
warning("Interface %s no longer appears valid.",
ip->name);
ip->dead = 1;
closesocket(l->fd);
remove_protocol(l);
adapter = AdapterFindInfo(ip);
if (adapter) {
RemoveEntryList(&adapter->ListEntry);
free(adapter);
}
}
return;
}
if (result == 0)
return;
if (bootp_packet_handler) {
ifrom.len = 4;
memcpy(ifrom.iabuf, &from.sin_addr, ifrom.len);
adapter = AdapterFindByHardwareAddress(u.packet.chaddr,
u.packet.hlen);
if (!adapter) {
warning("Discarding packet with a non-matching target physical address\n");
return;
}
(*bootp_packet_handler)(&adapter->DhclientInfo, &u.packet, result,
from.sin_port, ifrom, &hfrom);
}
}
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!");
return;
}
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);
}
}
}
struct protocol *
find_protocol_by_adapter(struct interface_info *info)
{
struct protocol *p;
for( p = protocols; p; p = p->next ) {
if( p->local == (void *)info ) return p;
}
return NULL;
}
int
interface_link_status(char *ifname)
{
return (1);
}

View file

@ -0,0 +1,165 @@
/* 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''.
*/
#define lint
#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,51 @@
/*
* 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
*/
#pragma once
#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
#if 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 */
#else /* DBG */
#define DH_DbgPrint(_t_, _x_)
#endif /* DBG */
/* 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,485 @@
/* $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''.
*/
#pragma once
#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
#include <pshpack1.h>
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 */
};
#include <poppack.h>
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/stat.h>
//#include <sys/time.h>
#include <ctype.h>
#include <fcntl.h>
#include <limits.h>
//#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.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;
#ifdef __REACTOS__
time_t obtained;
struct iaddr serveraddress;
#endif
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,
S_STATIC
};
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;
#ifdef _MSC_VER
void error(char *, ...);
int warning(char *, ...);
int note(char *, ...);
int debug(char *, ...);
int parse_warn(char *, ...);
#else
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)));
#endif
/* 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);
void dfree(void *, char *);
void free_hash_bucket(struct hash_bucket *, char *);
/* 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 *);
struct protocol *find_protocol_by_adapter( struct interface_info * );
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(struct interface_info *);
void write_client_lease(struct interface_info *, struct client_lease *, int);
void priv_script_init(struct interface_info *, char *, char *);
void priv_script_write_params(struct interface_info *, 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(struct interface_info *);
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);

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,100 @@
#ifndef ROSDHCP_H
#define ROSDHCP_H
#define WIN32_NO_STATUS
#include <winsock2.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h>
#include <iprtrmib.h>
#include <iphlpapi.h>
#include <dhcpcsdk.h>
#include <dhcp/rosdhcp_public.h>
#include <stdio.h>
#include <time.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_PANIC_TIMEOUT DHCP_REBOOT_TIMEOUT * 3
#define DHCP_BACKOFF_MAX 300
#define DHCP_DEFAULT_LEASE_TIME 43200 /* 12 hours */
#define _PATH_DHCLIENT_PID "\\systemroot\\system32\\drivers\\etc\\dhclient.pid"
typedef void *VOIDPTR;
typedef unsigned char u_int8_t;
typedef unsigned short u_int16_t;
typedef unsigned int u_int32_t;
typedef char *caddr_t;
#ifndef _SSIZE_T_DEFINED
#define _SSIZE_T_DEFINED
#undef ssize_t
#ifdef _WIN64
#if defined(__GNUC__) && defined(__STRICT_ANSI__)
typedef int ssize_t __attribute__ ((mode (DI)));
#else
typedef __int64 ssize_t;
#endif
#else
typedef int ssize_t;
#endif
#endif
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 *));
struct iaddr;
struct interface_info;
typedef struct _DHCP_ADAPTER {
LIST_ENTRY ListEntry;
MIB_IFROW IfMib;
MIB_IPFORWARDROW RouterMib;
MIB_IPADDRROW IfAddr;
SOCKADDR Address;
ULONG NteContext,NteInstance;
struct interface_info DhclientInfo;
struct client_state DhclientState;
struct client_config DhclientConfig;
struct sockaddr_in ListenAddr;
unsigned int BindStatus;
unsigned char recv_buf[1];
} DHCP_ADAPTER, *PDHCP_ADAPTER;
typedef DWORD (*PipeSendFunc)( COMM_DHCP_REPLY *Reply );
#define random rand
#define srandom srand
void AdapterInit(VOID);
BOOLEAN AdapterDiscover(VOID);
void AdapterStop(VOID);
extern PDHCP_ADAPTER AdapterGetFirst();
extern PDHCP_ADAPTER AdapterGetNext(PDHCP_ADAPTER);
extern PDHCP_ADAPTER AdapterFindIndex( unsigned int AdapterIndex );
extern PDHCP_ADAPTER AdapterFindInfo( struct interface_info *info );
extern PDHCP_ADAPTER AdapterFindByHardwareAddress( u_int8_t haddr[16], u_int8_t hlen );
extern HANDLE PipeInit();
extern VOID ApiInit();
extern VOID ApiFree();
extern VOID ApiLock();
extern VOID ApiUnlock();
extern DWORD DSQueryHWInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req );
extern DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req );
extern DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req );
extern DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req );
extern DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req );
extern DWORD DSGetAdapterInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req );
extern int inet_aton(const char *s, struct in_addr *addr);
int warn( char *format, ... );
#endif/*ROSDHCP_H*/

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,723 @@
/* $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>
#include <string.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);
return;
}
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));
strncpy(op, inet_ntoa(foo), opleft - 1);
op[opleft - 1] = ANSI_NULL;
opcount = strlen(op);
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 = (size_t) strncpy(op, *dp++ ? "true" : "false", opleft - 1);
op[opleft - 1] = ANSI_NULL;
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,120 @@
/* $Id: $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: subsys/system/dhcp/pipe.c
* PURPOSE: DHCP client pipe
* PROGRAMMER: arty
*/
#include <rosdhcp.h>
#define NDEBUG
#include <reactos/debug.h>
static HANDLE CommPipe = INVALID_HANDLE_VALUE, CommThread;
DWORD CommThrId;
#define COMM_PIPE_OUTPUT_BUFFER sizeof(COMM_DHCP_REQ)
#define COMM_PIPE_INPUT_BUFFER sizeof(COMM_DHCP_REPLY)
#define COMM_PIPE_DEFAULT_TIMEOUT 1000
DWORD PipeSend( COMM_DHCP_REPLY *Reply ) {
DWORD Written = 0;
BOOL Success =
WriteFile( CommPipe,
Reply,
sizeof(*Reply),
&Written,
NULL );
return Success ? Written : -1;
}
DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
DWORD BytesRead, BytesWritten;
COMM_DHCP_REQ Req;
COMM_DHCP_REPLY Reply;
BOOL Result, Connected;
while( TRUE ) {
Connected = ConnectNamedPipe( CommPipe, NULL ) ?
TRUE : GetLastError() == ERROR_PIPE_CONNECTED;
if (!Connected) {
DbgPrint("DHCP: Could not connect named pipe\n");
CloseHandle( CommPipe );
CommPipe = INVALID_HANDLE_VALUE;
break;
}
Result = ReadFile( CommPipe, &Req, sizeof(Req), &BytesRead, NULL );
if( Result ) {
switch( Req.Type ) {
case DhcpReqQueryHWInfo:
BytesWritten = DSQueryHWInfo( PipeSend, &Req );
break;
case DhcpReqLeaseIpAddress:
BytesWritten = DSLeaseIpAddress( PipeSend, &Req );
break;
case DhcpReqReleaseIpAddress:
BytesWritten = DSReleaseIpAddressLease( PipeSend, &Req );
break;
case DhcpReqRenewIpAddress:
BytesWritten = DSRenewIpAddressLease( PipeSend, &Req );
break;
case DhcpReqStaticRefreshParams:
BytesWritten = DSStaticRefreshParams( PipeSend, &Req );
break;
case DhcpReqGetAdapterInfo:
BytesWritten = DSGetAdapterInfo( PipeSend, &Req );
break;
default:
DPRINT1("Unrecognized request type %d\n", Req.Type);
ZeroMemory( &Reply, sizeof( COMM_DHCP_REPLY ) );
Reply.Reply = 0;
BytesWritten = PipeSend( &Reply );
break;
}
}
DisconnectNamedPipe( CommPipe );
}
return TRUE;
}
HANDLE PipeInit() {
CommPipe = CreateNamedPipeW
( DHCP_PIPE_NAME,
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1,
COMM_PIPE_OUTPUT_BUFFER,
COMM_PIPE_INPUT_BUFFER,
COMM_PIPE_DEFAULT_TIMEOUT,
NULL );
if( CommPipe == INVALID_HANDLE_VALUE ) {
DbgPrint("DHCP: Could not create named pipe\n");
return CommPipe;
}
CommThread = CreateThread( NULL, 0, PipeThreadProc, NULL, 0, &CommThrId );
if( !CommThread ) {
CloseHandle( CommPipe );
CommPipe = INVALID_HANDLE_VALUE;
}
return CommPipe;
}
VOID PipeDestroy() {
CloseHandle( CommPipe );
CommPipe = INVALID_HANDLE_VALUE;
}

View file

@ -0,0 +1,39 @@
#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 ) {
int result =
sendto( ip->wfdesc, (char *)p, size, 0,
(struct sockaddr *)broadcast, sizeof(*broadcast) );
if (result < 0) {
note ("send_packet: %x", result);
if (result == WSAENETUNREACH)
note ("send_packet: please consult README file%s",
" regarding broadcast address.");
}
return result;
}
ssize_t receive_packet(struct interface_info *ip,
unsigned char *packet_data,
size_t packet_len,
struct sockaddr_in *dest,
struct hardware *hardware ) {
int recv_addr_size = sizeof(*dest);
int result =
recvfrom (ip -> rfdesc, (char *)packet_data, packet_len, 0,
(struct sockaddr *)dest, &recv_addr_size );
return result;
}

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''.
*/
#define lint
#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,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,166 @@
#include <stdarg.h>
#include "rosdhcp.h"
#define NDEBUG
#include <reactos/debug.h>
char *piaddr( struct iaddr addr ) {
struct sockaddr_in sa;
memcpy(&sa.sin_addr,addr.iabuf,sizeof(sa.sin_addr));
return inet_ntoa( sa.sin_addr );
}
int note( char *format, ... ) {
char buf[0x100];
int ret;
va_list arg_begin;
va_start( arg_begin, format );
ret = _vsnprintf( buf, sizeof(buf), format, arg_begin );
DPRINT("NOTE: %s\n", buf);
return ret;
}
int debug( char *format, ... ) {
char buf[0x100];
int ret;
va_list arg_begin;
va_start( arg_begin, format );
ret = _vsnprintf( buf, sizeof(buf), format, arg_begin );
DPRINT("DEBUG: %s\n", buf);
return ret;
}
int warn( char *format, ... ) {
char buf[0x100];
int ret;
va_list arg_begin;
va_start( arg_begin, format );
ret = _vsnprintf( buf, sizeof(buf), format, arg_begin );
DPRINT("WARN: %s\n", buf);
return ret;
}
int warning( char *format, ... ) {
char buf[0x100];
int ret;
va_list arg_begin;
va_start( arg_begin, format );
ret = _vsnprintf( buf, sizeof(buf), format, arg_begin );
DPRINT("WARNING: %s\n", buf);
return ret;
}
void error( char *format, ... ) {
char buf[0x100];
va_list arg_begin;
va_start( arg_begin, format );
_vsnprintf( buf, sizeof(buf), format, arg_begin );
DPRINT1("ERROR: %s\n", buf);
}
int16_t getShort( unsigned char *data ) {
return (int16_t) ntohs(*(int16_t*) data);
}
u_int16_t getUShort( unsigned char *data ) {
return (u_int16_t) ntohs(*(u_int16_t*) data);
}
int32_t getLong( unsigned char *data ) {
return (int32_t) ntohl(*(u_int32_t*) data);
}
u_int32_t getULong( unsigned char *data ) {
return ntohl(*(u_int32_t*)data);
}
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 ); }
int read_client_conf(struct interface_info *ifi) {
/* What a strange dance */
struct client_config *config;
char ComputerName [MAX_COMPUTERNAME_LENGTH + 1];
LPSTR lpCompName;
DWORD ComputerNameSize = sizeof ComputerName / sizeof ComputerName[0];
if ((ifi!= NULL) && (ifi->client->config != NULL))
config = ifi->client->config;
else
{
warn("util.c read_client_conf poorly implemented!");
return 0;
}
GetComputerName(ComputerName, & ComputerNameSize);
debug("Hostname: %s, length: %lu",
ComputerName, ComputerNameSize);
/* This never gets freed since it's only called once */
lpCompName =
HeapAlloc(GetProcessHeap(), 0, ComputerNameSize + 1);
if (lpCompName !=NULL) {
memcpy(lpCompName, ComputerName, ComputerNameSize + 1);
/* Send our hostname, some dhcpds use this to update DNS */
config->send_options[DHO_HOST_NAME].data = (u_int8_t*)lpCompName;
config->send_options[DHO_HOST_NAME].len = ComputerNameSize;
debug("Hostname: %s, length: %d",
config->send_options[DHO_HOST_NAME].data,
config->send_options[DHO_HOST_NAME].len);
} else {
error("Failed to allocate heap for hostname");
}
/* Both Linux and Windows send this */
config->send_options[DHO_DHCP_CLIENT_IDENTIFIER].data =
ifi->hw_address.haddr;
config->send_options[DHO_DHCP_CLIENT_IDENTIFIER].len =
ifi->hw_address.hlen;
/* Setup the requested option list */
config->requested_options
[config->requested_option_count++] = DHO_SUBNET_MASK;
config->requested_options
[config->requested_option_count++] = DHO_BROADCAST_ADDRESS;
config->requested_options
[config->requested_option_count++] = DHO_TIME_OFFSET;
config->requested_options
[config->requested_option_count++] = DHO_ROUTERS;
config->requested_options
[config->requested_option_count++] = DHO_DOMAIN_NAME;
config->requested_options
[config->requested_option_count++] = DHO_DOMAIN_NAME_SERVERS;
config->requested_options
[config->requested_option_count++] = DHO_HOST_NAME;
config->requested_options
[config->requested_option_count++] = DHO_NTP_SERVERS;
warn("util.c read_client_conf poorly implemented!");
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;
}

View file

@ -8,6 +8,8 @@
#include "iphlpapi_private.h"
#include "dhcp.h"
#include "dhcpcsdk.h"
#include "dhcpcapi.h"
#include <assert.h>
#define NDEBUG
@ -25,6 +27,27 @@ DWORD getDhcpInfoForAdapter(DWORD AdapterIndex,
time_t *LeaseObtained,
time_t *LeaseExpires)
{
return DhcpRosGetAdapterInfo(AdapterIndex, DhcpEnabled, DhcpServer,
LeaseObtained, LeaseExpires);
DWORD Status, Version = 0;
Status = DhcpCApiInitialize(&Version);
if (Status == ERROR_NOT_READY)
{
/* The DHCP server isn't running yet */
*DhcpEnabled = FALSE;
*DhcpServer = htonl(INADDR_NONE);
*LeaseObtained = 0;
*LeaseExpires = 0;
return ERROR_SUCCESS;
}
else if (Status != ERROR_SUCCESS)
{
return Status;
}
Status = DhcpRosGetAdapterInfo(AdapterIndex, DhcpEnabled, DhcpServer,
LeaseObtained, LeaseExpires);
DhcpCApiCleanup();
return Status;
}

View file

@ -2,7 +2,7 @@
<importlibrary definition="iphlpapi.spec" />
<include base="iphlpapi">.</include>
<include base="ReactOS">include/reactos/wine</include>
<include base="dhcp">include</include>
<include base="dhcpcsvc">include</include>
<include base="tdilib">.</include>
<library>wine</library>
<library>ntdll</library>

View file

@ -49,7 +49,7 @@
#include "route.h"
#include "wine/debug.h"
#include "dhcpcsdk.h"
#include "dhcp/rosdhcp_public.h"
#include "dhcpcapi.h"
WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
@ -63,6 +63,7 @@ typedef struct _NAME_SERVER_LIST_CONTEXT {
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
DWORD Version;
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls( hinstDLL );
@ -1944,30 +1945,23 @@ DWORD WINAPI GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIP
*/
DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
{
COMM_DHCP_REPLY Reply;
COMM_DHCP_REQ Request;
DWORD BytesRead;
Request.AdapterIndex = AdapterInfo->Index;
Request.Type = DhcpReqReleaseIpAddress;
TRACE("AdapterInfo %p\n", AdapterInfo);
if (CallNamedPipe(DHCP_PIPE_NAME,
&Request,
sizeof(Request),
&Reply,
sizeof(Reply),
&BytesRead,
NMPWAIT_USE_DEFAULT_WAIT))
{
if (Reply.Reply)
return NO_ERROR;
DWORD Status, Version = 0;
if (!AdapterInfo || !AdapterInfo->Name)
return ERROR_INVALID_PARAMETER;
}
return ERROR_PROC_NOT_FOUND;
/* Maybe we should do this in DllMain */
if (DhcpCApiInitialize(&Version) != ERROR_SUCCESS)
return ERROR_PROC_NOT_FOUND;
if (DhcpReleaseIpAddressLease(AdapterInfo->Index))
Status = ERROR_SUCCESS;
else
Status = ERROR_PROC_NOT_FOUND;
DhcpCApiCleanup();
return Status;
}
@ -1985,30 +1979,23 @@ DWORD WINAPI IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
*/
DWORD WINAPI IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
{
COMM_DHCP_REPLY Reply;
COMM_DHCP_REQ Request;
DWORD BytesRead;
Request.AdapterIndex = AdapterInfo->Index;
Request.Type = DhcpReqRenewIpAddress;
TRACE("AdapterInfo %p\n", AdapterInfo);
if (CallNamedPipe(DHCP_PIPE_NAME,
&Request,
sizeof(Request),
&Reply,
sizeof(Reply),
&BytesRead,
NMPWAIT_USE_DEFAULT_WAIT))
{
if (Reply.Reply)
return NO_ERROR;
DWORD Status, Version = 0;
if (!AdapterInfo || !AdapterInfo->Name)
return ERROR_INVALID_PARAMETER;
}
return ERROR_PROC_NOT_FOUND;
/* Maybe we should do this in DllMain */
if (DhcpCApiInitialize(&Version) != ERROR_SUCCESS)
return ERROR_PROC_NOT_FOUND;
if (DhcpRenewIpAddressLease(AdapterInfo->Index))
Status = ERROR_SUCCESS;
else
Status = ERROR_PROC_NOT_FOUND;
DhcpCApiCleanup();
return Status;
}

View file

@ -1,17 +1,33 @@
#ifndef _DHCPCAPI_H
#define _DHCPCAPI_H
#include <windows.h>
#include <accctrl.h>
#ifdef __cplusplus
extern "C" {
#endif
VOID WINAPI DhcpLeaseIpAddress( ULONG AdapterIndex );
VOID WINAPI DhcpReleaseIpAddressLease( ULONG AdapterIndex );
VOID WINAPI DhcpStaticRefreshParams
( ULONG AdapterIndex, ULONG IpAddress, ULONG NetMask );
DWORD APIENTRY DhcpLeaseIpAddress( DWORD AdapterIndex );
DWORD APIENTRY DhcpQueryHWInfo( DWORD AdapterIndex,
PDWORD MediaType,
PDWORD Mtu,
PDWORD Speed );
DWORD APIENTRY DhcpReleaseIpAddressLease( DWORD AdapterIndex );
DWORD APIENTRY DhcpRenewIpAddressLease( DWORD AdapterIndex );
DWORD APIENTRY DhcpStaticRefreshParams( DWORD AdapterIndex,
DWORD Address,
DWORD Netmask );
DWORD APIENTRY
DhcpNotifyConfigChange(LPWSTR ServerName,
LPWSTR AdapterName,
BOOL NewIpAddress,
DWORD IpIndex,
DWORD IpAddress,
DWORD SubnetMask,
int DhcpAction);
DWORD APIENTRY DhcpRosGetAdapterInfo( DWORD AdapterIndex,
PBOOL DhcpEnabled,
PDWORD DhcpServer,
time_t *LeaseObtained,
time_t *LeaseExpires );
#ifdef __cplusplus
}