mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2426 lines
61 KiB
2426 lines
61 KiB
/*++
|
|
|
|
Copyright (c) 1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dhcpcmd.c
|
|
|
|
Abstract:
|
|
|
|
This file contains program to test all DHCP APIs.
|
|
|
|
Author:
|
|
|
|
Madan Appiah (madana) 5-Oct-1993
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
#include <winsock.h>
|
|
#include <dhcp.h>
|
|
#include <dhcpapi.h>
|
|
#include <dhcplib.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <wchar.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <jet.h> // for JET_cbColumnMost
|
|
|
|
#include <heapx.h>
|
|
|
|
#ifdef DBG
|
|
#ifdef __DHCP_USE_DEBUG_HEAP__
|
|
|
|
|
|
#pragma message ( "*** DHCPCMD will use debug heap ***" )
|
|
|
|
#define DhcpAllocateMemory(x) calloc(1,x)
|
|
#define DhcpFreeMemory(x) free(x)
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
typedef enum _COMMAND_CODE {
|
|
AddIpRange,
|
|
AddReservedIp,
|
|
EnumClients,
|
|
MibCounts,
|
|
ServerConfig,
|
|
GetDhcpVersion,
|
|
SetSuperScope,
|
|
DeleteSuperScope,
|
|
GetSuperScopeTable,
|
|
RemoveSubscope,
|
|
#if 0
|
|
CheckDB,
|
|
CreateSubnet,
|
|
AddExcludeRange,
|
|
RemoveReservedIp,
|
|
RemoveExcludeRange,
|
|
SetSubnetState,
|
|
DeleteSubnet,
|
|
CreateOption,
|
|
SetGlobalOptionValue,
|
|
SetGlobalOptionValues,
|
|
SetSubnetOptionValue,
|
|
SetReservedOptionValue,
|
|
EnumOptions,
|
|
#endif // 0
|
|
UnknownCommand
|
|
} COMMAND_CODE, *LPCOMMAND_CODE;
|
|
|
|
typedef struct _COMMAND_INFO {
|
|
LPSTR CommandName;
|
|
COMMAND_CODE CommandCode;
|
|
} COMMAND_INFO, *LPCOMMAND_INFO;
|
|
|
|
LPWSTR GlobalServerIpAddressUnicodeString = NULL;
|
|
LPSTR GlobalServerIpAddressAnsiString = NULL;
|
|
DWORD GlobalClientCount;
|
|
DWORD g_dwMajor = (DWORD) -1 ,
|
|
g_dwMinor = (DWORD) -1; // version control
|
|
|
|
COMMAND_INFO GlobalCommandInfo[] = {
|
|
{"AddIpRange", AddIpRange },
|
|
{"AddReservedIp", AddReservedIp },
|
|
{"EnumClients", EnumClients },
|
|
{"MibCounts", MibCounts },
|
|
{"ServerConfig", ServerConfig },
|
|
{"GetVersion", GetDhcpVersion },
|
|
{"SetSuperScope", SetSuperScope },
|
|
{"DeleteSuperScope", DeleteSuperScope },
|
|
{"GetSuperScopeTable", GetSuperScopeTable },
|
|
{"RemoveSubscope", RemoveSubscope },
|
|
#if 0
|
|
{"CheckDB", CheckDB },
|
|
{"CreateSubnet", CreateSubnet },
|
|
{"AddExcludeRange", AddExcludeRange },
|
|
{"RemoveReservedIp", RemoveReservedIp },
|
|
{"RemoveExcludeRange", RemoveExcludeRange },
|
|
{"SetSubnetState", SetSubnetState },
|
|
{"DeleteSubnet", DeleteSubnet },
|
|
{"CreateOption", CreateOption },
|
|
{"SetGlobalOptionValue", SetGlobalOptionValue },
|
|
{"SetGlobalOptionValues", SetGlobalOptionValues },
|
|
{"SetSubnetOptionValue", SetSubnetOptionValue },
|
|
{"SetReservedOptionValue",SetReservedOptionValue },
|
|
{"EnumOptions", EnumOptions}
|
|
#endif //0
|
|
};
|
|
|
|
typedef enum _CONFIG_COMMAND_CODE {
|
|
ConfigAPIProtocolSupport,
|
|
ConfigDatabaseName,
|
|
ConfigDatabasePath,
|
|
ConfigBackupPath,
|
|
ConfigBackupInterval,
|
|
ConfigDatabaseLoggingFlag,
|
|
ConfigRestoreFlag,
|
|
ConfigDatabaseCleanupInterval,
|
|
ConfigDebugFlag,
|
|
ConfigActivityLog,
|
|
ConfigPingRetries,
|
|
ConfigBootFileTable,
|
|
UnknownConfigCommand
|
|
} CONFIG_COMMAND_CODE, *LPCONFIG_COMMAND_CODE;
|
|
|
|
typedef struct _CONFIG_COMMAND_INFO {
|
|
LPSTR CommandName;
|
|
CONFIG_COMMAND_CODE CommandCode;
|
|
} CONFIG_COMMAND_INFO, *LPCONFIG_COMMAND_INFO;
|
|
|
|
CONFIG_COMMAND_INFO GlobalConfigCommandInfo[] =
|
|
{
|
|
{"APIProtocolSupport", ConfigAPIProtocolSupport },
|
|
{"DatabaseName", ConfigDatabaseName },
|
|
{"DatabasePath", ConfigDatabasePath },
|
|
{"BackupPath", ConfigBackupPath },
|
|
{"BackupInterval", ConfigBackupInterval },
|
|
{"DatabaseLoggingFlag", ConfigDatabaseLoggingFlag },
|
|
{"RestoreFlag", ConfigRestoreFlag },
|
|
{"DatabaseCleanupInterval", ConfigDatabaseCleanupInterval },
|
|
{"DebugFlag", ConfigDebugFlag },
|
|
{"ActivityLog", ConfigActivityLog },
|
|
{"PingRetries", ConfigPingRetries },
|
|
{"BootFileTable", ConfigBootFileTable }
|
|
};
|
|
|
|
|
|
|
|
|
|
#define DHCPCMD_VERSION_MAJOR 4
|
|
#define DHCPCMD_VERSION_MINOR 1
|
|
|
|
|
|
#if DBG
|
|
|
|
VOID
|
|
DhcpPrintRoutine(
|
|
IN DWORD DebugFlag,
|
|
IN LPSTR Format,
|
|
...
|
|
)
|
|
|
|
{
|
|
|
|
#define WSTRSIZE( wsz ) ( ( wcslen( wsz ) + 1 ) * sizeof( WCHAR ) )
|
|
|
|
#define MAX_PRINTF_LEN 1024 // Arbitrary.
|
|
|
|
va_list arglist;
|
|
char OutputBuffer[MAX_PRINTF_LEN];
|
|
ULONG length = 0;
|
|
|
|
//
|
|
// Put a the information requested by the caller onto the line
|
|
//
|
|
|
|
va_start(arglist, Format);
|
|
length += (ULONG) vsprintf(&OutputBuffer[length], Format, arglist);
|
|
va_end(arglist);
|
|
|
|
DhcpAssert(length <= MAX_PRINTF_LEN);
|
|
|
|
//
|
|
// Output to the debug terminal,
|
|
//
|
|
|
|
printf( "%s", OutputBuffer);
|
|
}
|
|
|
|
#endif // DBG
|
|
DWORD
|
|
SetOptionDataType(
|
|
LPSTR OptionTypeString,
|
|
LPSTR OptionValueString,
|
|
LPDHCP_OPTION_DATA_ELEMENT OptionData,
|
|
LPWSTR *UnicodeOptionValueString
|
|
)
|
|
{
|
|
DHCP_OPTION_DATA_TYPE OptionType;
|
|
DHCP_OPTION_ID OptionValue;
|
|
|
|
if( _stricmp( OptionTypeString, "BYTE") == 0 ) {
|
|
OptionType = DhcpByteOption;
|
|
} else if( _stricmp( OptionTypeString, "WORD") == 0 ) {
|
|
OptionType = DhcpWordOption;
|
|
} else if( _stricmp( OptionTypeString, "DWORD") == 0 ) {
|
|
OptionType = DhcpDWordOption;
|
|
} else if( _stricmp( OptionTypeString, "STRING") == 0 ) {
|
|
OptionType = DhcpStringDataOption;
|
|
} else if( _stricmp( OptionTypeString, "IPADDRESS") == 0 ) {
|
|
OptionType = DhcpIpAddressOption;
|
|
} else {
|
|
printf("OptionType either Unknown or not supported, %s.\n",
|
|
OptionTypeString );
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
OptionData->OptionType = OptionType;
|
|
|
|
switch( OptionType ) {
|
|
case DhcpByteOption:
|
|
OptionValue = strtoul( OptionValueString, NULL, 0 );
|
|
|
|
if( OptionValue | ~((BYTE)-1) ) {
|
|
printf("DefValue is too large (%ld).\n", OptionValue );
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
OptionData->Element.ByteOption = (BYTE)OptionValue;
|
|
break;
|
|
|
|
case DhcpWordOption:
|
|
OptionValue = strtoul( OptionValueString, NULL, 0 );
|
|
|
|
if( OptionValue | ~((WORD)-1) ) {
|
|
printf("DefValue is too large (%ld).\n", OptionValue );
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
OptionData->Element.WordOption = (WORD)OptionValue;
|
|
break;
|
|
|
|
case DhcpDWordOption:
|
|
OptionValue = strtoul( OptionValueString, NULL, 0 );
|
|
OptionData->Element.DWordOption = (DWORD)OptionValue;
|
|
break;
|
|
|
|
|
|
case DhcpIpAddressOption:
|
|
OptionData->Element.IpAddressOption =
|
|
DhcpDottedStringToIpAddress(OptionValueString);
|
|
break;
|
|
|
|
case DhcpStringDataOption:
|
|
*UnicodeOptionValueString =
|
|
DhcpOemToUnicode( OptionValueString, NULL );
|
|
if( UnicodeOptionValueString == NULL ) {
|
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
OptionData->Element.StringDataOption = *UnicodeOptionValueString;
|
|
|
|
default:
|
|
DhcpAssert(FALSE);
|
|
printf("CreateOptionValue: Unknown OptionType \n");
|
|
return( ERROR_INVALID_PARAMETER );
|
|
break;
|
|
}
|
|
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
COMMAND_CODE
|
|
DecodeCommand(
|
|
LPSTR CommandName
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD NumCommands;
|
|
|
|
NumCommands = sizeof(GlobalCommandInfo) / sizeof(COMMAND_INFO);
|
|
DhcpAssert( NumCommands <= UnknownCommand );
|
|
for( i = 0; i < NumCommands; i++) {
|
|
if( _stricmp( CommandName, GlobalCommandInfo[i].CommandName ) == 0 ) {
|
|
return( GlobalCommandInfo[i].CommandCode );
|
|
}
|
|
}
|
|
return( UnknownCommand );
|
|
}
|
|
|
|
VOID
|
|
PrintCommands(
|
|
VOID
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD NumCommands;
|
|
|
|
NumCommands = sizeof(GlobalCommandInfo) / sizeof(COMMAND_INFO);
|
|
DhcpAssert( NumCommands <= UnknownCommand );
|
|
for( i = 0; i < NumCommands; i++) {
|
|
printf( " %s\n", GlobalCommandInfo[i].CommandName );
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
|
|
DWORD
|
|
ProcessCreateSubnet(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_SUBNET_INFO SubnetInfo;
|
|
LPWSTR UnicodeSubnetName = NULL;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress SubnetMask SubnetName>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress CreateSubnet [Command Parameters].\n"
|
|
"<Command Parameters> - <SubnetAddress SubnetMask SubnetName>.\n" );
|
|
Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
|
|
SubnetInfo.SubnetAddress =
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]);
|
|
SubnetInfo.SubnetMask =
|
|
DhcpDottedStringToIpAddress(CommandArgv[1]);
|
|
|
|
UnicodeSubnetName = DhcpOemToUnicode( CommandArgv[2], NULL );
|
|
DhcpAssert( UnicodeSubnetName != NULL );
|
|
|
|
SubnetInfo.SubnetName = UnicodeSubnetName;
|
|
SubnetInfo.SubnetComment = NULL;
|
|
SubnetInfo.PrimaryHost.IpAddress =
|
|
DhcpDottedStringToIpAddress(GlobalServerIpAddressAnsiString);
|
|
|
|
SubnetInfo.PrimaryHost.NetBiosName = NULL;
|
|
SubnetInfo.PrimaryHost.HostName = NULL;
|
|
SubnetInfo.SubnetState = DhcpSubnetEnabled;
|
|
|
|
Error = DhcpCreateSubnet(
|
|
GlobalServerIpAddressUnicodeString,
|
|
SubnetInfo.SubnetAddress,
|
|
&SubnetInfo );
|
|
|
|
Cleanup:
|
|
|
|
if( UnicodeSubnetName != NULL ) {
|
|
DhcpFreeMemory( UnicodeSubnetName );
|
|
}
|
|
|
|
return( Error );
|
|
}
|
|
|
|
#endif // 0
|
|
|
|
BOOL
|
|
IsValidServerVersion(
|
|
DWORD dwMajor,
|
|
DWORD dwMinor
|
|
)
|
|
{
|
|
DWORD dwServerVersion = MAKEWORD( dwMajor, dwMinor );
|
|
return ( dwServerVersion >=
|
|
MAKEWORD( DHCPCMD_VERSION_MAJOR,
|
|
DHCPCMD_VERSION_MINOR ));
|
|
}
|
|
|
|
DWORD
|
|
ProcessAddIpRange(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_IP_RANGE IpRange;
|
|
DHCP_SUBNET_ELEMENT_DATA Element;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress IpRangeStart IpRangeEnd>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress AddIpRange [Command Parameters].\n"
|
|
"<Command Parameters> - <SubnetAddress IpRangeStart IpRangeEnd>.\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
IpRange.StartAddress = DhcpDottedStringToIpAddress(CommandArgv[1]);
|
|
IpRange.EndAddress = DhcpDottedStringToIpAddress(CommandArgv[2]);
|
|
|
|
Element.ElementType = DhcpIpRanges;
|
|
Element.Element.IpRange = &IpRange;
|
|
|
|
Error = DhcpAddSubnetElement(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
&Element );
|
|
|
|
return( Error );
|
|
}
|
|
|
|
#define COMMAND_ARG_TYPE 5
|
|
|
|
DWORD
|
|
ProcessBootpParameters(
|
|
DWORD cArgs,
|
|
LPSTR *ppszArgs,
|
|
DHCP_IP_RESERVATION_V4 *pReservation
|
|
)
|
|
{
|
|
DWORD dwResult = ERROR_SUCCESS;
|
|
|
|
|
|
if ( cArgs > COMMAND_ARG_TYPE )
|
|
{
|
|
// user specified the allowed client type
|
|
|
|
if ( !_stricmp( ppszArgs[ COMMAND_ARG_TYPE ], "bootp" ) )
|
|
{
|
|
pReservation->bAllowedClientTypes = CLIENT_TYPE_BOOTP;
|
|
}
|
|
else if ( !_stricmp ( ppszArgs[ COMMAND_ARG_TYPE ], "dhcp" ) )
|
|
{
|
|
pReservation->bAllowedClientTypes = CLIENT_TYPE_DHCP;
|
|
}
|
|
else if ( !_stricmp ( ppszArgs[ COMMAND_ARG_TYPE ], "both" ) )
|
|
{
|
|
pReservation->bAllowedClientTypes = CLIENT_TYPE_BOTH;
|
|
}
|
|
else
|
|
{
|
|
printf( "Specify BOOTP, DHCP, or BOTH for reservation type.\n" );
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// allow dhcp clients by default.
|
|
pReservation->bAllowedClientTypes = CLIENT_TYPE_DHCP;
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
t_done:
|
|
|
|
return dwResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
ProcessAddReservedIp(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
#define MAX_ADDRESS_LENGTH 64 // 64 bytes
|
|
#define COMMAND_ARG_CLIENT_COMMENT 4
|
|
|
|
DWORD Error;
|
|
DHCP_SUBNET_ELEMENT_DATA_V4 Element;
|
|
DHCP_IP_RESERVATION_V4 ReserveElement;
|
|
DHCP_CLIENT_UID ClientUID;
|
|
BYTE Address[MAX_ADDRESS_LENGTH];
|
|
DWORD i;
|
|
DHCP_IP_ADDRESS ReservedIpAddress;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress ReservedIp HWAddressString>
|
|
//
|
|
|
|
//
|
|
// if the server version is 4.1 or greater, <AllowedClientTypes> and <BootFileString> can
|
|
// also be supplied
|
|
//
|
|
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress AddReservedIp "
|
|
"[Command Parameters].\n"
|
|
"<Command Parameters> - "
|
|
"<SubnetAddress ReservedIp HWAddressString [ClientName] [ClientComment]"
|
|
" [DHCP | BOOTP | BOTH]>\n" );
|
|
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
//
|
|
// make HardwareAddress.
|
|
//
|
|
|
|
ClientUID.DataLength = strlen(CommandArgv[2]);
|
|
if( ClientUID.DataLength % 2 != 0 ) {
|
|
//
|
|
// address must be even length.
|
|
//
|
|
|
|
printf("ProcessAddReservedIp: address must be even length.\n");
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
ClientUID.DataLength /= 2;
|
|
DhcpAssert( ClientUID.DataLength < MAX_ADDRESS_LENGTH );
|
|
|
|
i = DhcpStringToHwAddress( (LPSTR)Address, CommandArgv[2] );
|
|
DhcpAssert( i == ClientUID.DataLength );
|
|
ClientUID.Data = Address;
|
|
|
|
//
|
|
// make reserve element.
|
|
//
|
|
|
|
ReservedIpAddress = DhcpDottedStringToIpAddress(CommandArgv[1]);
|
|
ReserveElement.ReservedIpAddress = ReservedIpAddress;
|
|
ReserveElement.ReservedForClient = &ClientUID;
|
|
|
|
Element.ElementType = DhcpReservedIps;
|
|
Element.Element.ReservedIp = &ReserveElement;
|
|
|
|
Error = ProcessBootpParameters( CommandArgc, CommandArgv, &ReserveElement );
|
|
if ( ERROR_SUCCESS != Error )
|
|
{
|
|
return Error;
|
|
}
|
|
|
|
Error = DhcpAddSubnetElementV4(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
&Element );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
return( Error );
|
|
}
|
|
|
|
//
|
|
// if we are asked to set the client name, do so.
|
|
//
|
|
|
|
if( CommandArgc > 3 ) {
|
|
|
|
DHCP_SEARCH_INFO ClientSearchInfo;
|
|
LPDHCP_CLIENT_INFO_V4 ClientInfo = NULL;
|
|
LPWSTR UnicodeClientName = NULL;
|
|
LPWSTR UnicodeClientComment = NULL;
|
|
|
|
//
|
|
// set client name.
|
|
//
|
|
|
|
ClientSearchInfo.SearchType = DhcpClientIpAddress;
|
|
ClientSearchInfo.SearchInfo.ClientIpAddress = ReservedIpAddress;
|
|
|
|
do {
|
|
|
|
Error = DhcpGetClientInfoV4(
|
|
GlobalServerIpAddressUnicodeString,
|
|
&ClientSearchInfo,
|
|
&ClientInfo );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
break;
|
|
}
|
|
|
|
UnicodeClientName = DhcpOemToUnicode( CommandArgv[3], NULL );
|
|
|
|
if( UnicodeClientName == NULL ) {
|
|
Error = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
if ( ( wcslen( UnicodeClientName ) + 1 ) * sizeof(WCHAR) > JET_cbColumnMost ) {
|
|
printf("ProcessAddReservedIp: Client Name too long\n");
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// if client comment is also given in the argument, store that
|
|
// as well.
|
|
//
|
|
if ( CommandArgc > COMMAND_ARG_CLIENT_COMMENT ) {
|
|
|
|
UnicodeClientComment = DhcpOemToUnicode( CommandArgv[COMMAND_ARG_CLIENT_COMMENT], NULL );
|
|
|
|
if (!UnicodeClientComment ) {
|
|
Error = ERROR_NOT_ENOUGH_MEMORY;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// check the size here.
|
|
//
|
|
if ( ( wcslen( UnicodeClientComment ) + 1 ) * sizeof(WCHAR) > JET_cbColumnMost ) {
|
|
printf("ProcessAddReservedIp: Client Comment too long\n");
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
ClientInfo->ClientComment = UnicodeClientComment;
|
|
|
|
|
|
|
|
}
|
|
|
|
ClientInfo->ClientName = UnicodeClientName;
|
|
|
|
} while ( FALSE );
|
|
|
|
if ( Error == ERROR_SUCCESS ) {
|
|
|
|
Error = DhcpSetClientInfoV4(
|
|
GlobalServerIpAddressUnicodeString,
|
|
ClientInfo );
|
|
|
|
} else {
|
|
//
|
|
// Cleanup.
|
|
//
|
|
if ( ClientInfo ) {
|
|
DhcpRpcFreeMemory( ClientInfo );
|
|
}
|
|
if ( UnicodeClientName ) {
|
|
DhcpFreeMemory( UnicodeClientName );
|
|
}
|
|
if ( UnicodeClientComment ) {
|
|
DhcpFreeMemory( UnicodeClientComment );
|
|
}
|
|
}
|
|
|
|
} // if( CommandArgc > 3 )
|
|
|
|
|
|
return( Error );
|
|
}
|
|
|
|
#if 0
|
|
|
|
DWORD
|
|
ProcessAddExcludeRange(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_IP_RANGE IpRange;
|
|
DHCP_SUBNET_ELEMENT_DATA Element;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress IpRangeStart IpRangeEnd>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress AddExcludeRange [Command Parameters].\n"
|
|
"<Command Parameters> - <SubnetAddress IpRangeStart IpRangeEnd>.\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
IpRange.StartAddress = DhcpDottedStringToIpAddress(CommandArgv[1]);
|
|
IpRange.EndAddress = DhcpDottedStringToIpAddress(CommandArgv[2]);
|
|
|
|
Element.ElementType = DhcpExcludedIpRanges;
|
|
Element.Element.IpRange = &IpRange;
|
|
|
|
Error = DhcpAddSubnetElement(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
&Element );
|
|
|
|
return( Error );
|
|
}
|
|
|
|
DWORD
|
|
ProcessRemoveExcludeRange(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_SUBNET_ELEMENT_DATA Element;
|
|
DHCP_IP_RANGE IpRange;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress IpRangeStart IpRangeEnd>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress RemoveExcludeRange [Command Parameters].\n"
|
|
"<Command Parameters> - <SubnetAddress IpRangeStart IpRangeEnd>.\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
IpRange.StartAddress = DhcpDottedStringToIpAddress(CommandArgv[1]);
|
|
IpRange.EndAddress = DhcpDottedStringToIpAddress(CommandArgv[2]);
|
|
|
|
Element.ElementType = DhcpExcludedIpRanges;
|
|
Element.Element.ExcludeIpRange = &IpRange;
|
|
|
|
Error = DhcpRemoveSubnetElement(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
&Element,
|
|
DhcpFullForce );
|
|
|
|
return( Error );
|
|
}
|
|
|
|
DWORD
|
|
ProcessRemoveReservedIp(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_SUBNET_ELEMENT_DATA_V4 Element;
|
|
DHCP_IP_RESERVATION_V4 ReserveElement;
|
|
DHCP_CLIENT_UID ClientUID;
|
|
BYTE Address[MAX_ADDRESS_LENGTH];
|
|
DWORD i;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress ReservedIp HWAddressString>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress RemoveReservedIp "
|
|
"[Command Parameters].\n"
|
|
"<Command Parameters> - "
|
|
"<SubnetAddress ReservedIp HWAddressString>.\n" );
|
|
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
//
|
|
// make HardwareAddress.
|
|
//
|
|
|
|
ClientUID.DataLength = strlen(CommandArgv[2]);
|
|
if( ClientUID.DataLength % 2 != 0 ) {
|
|
//
|
|
// address must be even length.
|
|
//
|
|
|
|
printf("ProcessAddReservedIp: address must be even length.\n");
|
|
return( ERROR_INVALID_PARAMETER );
|
|
}
|
|
|
|
ClientUID.DataLength /= 2;
|
|
DhcpAssert( ClientUID.DataLength < MAX_ADDRESS_LENGTH );
|
|
|
|
i = DhcpStringToHwAddress( (LPSTR)Address, CommandArgv[2] );
|
|
DhcpAssert( i == ClientUID.DataLength );
|
|
ClientUID.Data = Address;
|
|
|
|
//
|
|
// make reserve element.
|
|
//
|
|
|
|
ReserveElement.ReservedIpAddress = DhcpDottedStringToIpAddress(CommandArgv[1]);
|
|
ReserveElement.ReservedForClient = &ClientUID;
|
|
|
|
Element.ElementType = DhcpReservedIps;
|
|
Element.Element.ReservedIp = &ReserveElement;
|
|
|
|
Error = DhcpRemoveSubnetElement(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
&Element,
|
|
DhcpFullForce );
|
|
|
|
return( Error );
|
|
}
|
|
|
|
DWORD
|
|
ProcessSetSubnetState(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
LPDHCP_SUBNET_INFO SubnetInfo;
|
|
LPWSTR UnicodeSubnetName = NULL;
|
|
DWORD State;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress SubnetMask SubnetName>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 2 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress SetSubnetState [Command Parameters].\n"
|
|
"<Command Parameters> - <SubnetAddress State>.\n" );
|
|
Error = ERROR_SUCCESS;
|
|
return( Error );
|
|
}
|
|
|
|
Error = DhcpGetSubnetInfo(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
&SubnetInfo );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
return( Error );
|
|
}
|
|
|
|
State = strtoul( CommandArgv[1], NULL, 0 );
|
|
|
|
if( State == 0 ) {
|
|
if( SubnetInfo->SubnetState == DhcpSubnetEnabled ) {
|
|
Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
SubnetInfo->SubnetState = DhcpSubnetEnabled;
|
|
}
|
|
else {
|
|
if( SubnetInfo->SubnetState == DhcpSubnetDisabled ) {
|
|
Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
SubnetInfo->SubnetState = DhcpSubnetDisabled;
|
|
}
|
|
|
|
Error = DhcpSetSubnetInfo(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
SubnetInfo );
|
|
Cleanup:
|
|
|
|
if( SubnetInfo != NULL ) {
|
|
DhcpFreeMemory( SubnetInfo );
|
|
}
|
|
|
|
return( Error );
|
|
|
|
}
|
|
|
|
DWORD
|
|
ProcessDeleteSubnet(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
printf("This command is not implemented yet !\n");
|
|
return( ERROR_CALL_NOT_IMPLEMENTED );
|
|
}
|
|
|
|
ProcessCreateOption(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_OPTION OptionInfo;
|
|
DHCP_OPTION_ID OptionID;
|
|
LPWSTR UnicodeOptionName = NULL;
|
|
LPWSTR UnicodeOptionValueString = NULL;
|
|
DHCP_OPTION_DATA_ELEMENT OptionData;
|
|
|
|
//
|
|
// Expected Parameters are :
|
|
// <OptionID OptionName DefValueType DefValue>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 2 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress CreateOption [Command Parameters].\n"
|
|
"<Command Parameters> - <OptionID OptionName <DefValueType DefValue>>.\n");
|
|
printf("<DefValueType> : <BYTE | WORD | DWORD | STRING | IPADDRESS>.\n");
|
|
Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
|
|
OptionID = strtoul( CommandArgv[0], NULL, 0 );
|
|
if( (OptionID < 0) || (OptionID > 255) ) {
|
|
printf("OptionID too large (%ld).\n", OptionID );
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
OptionInfo.OptionID = OptionID;
|
|
|
|
UnicodeOptionName = DhcpOemToUnicode( CommandArgv[1], NULL );
|
|
if( UnicodeOptionName == NULL ) {
|
|
Error = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
OptionInfo.OptionName = UnicodeOptionName;
|
|
OptionInfo.OptionComment = NULL;
|
|
|
|
if( CommandArgc >= 4 ) {
|
|
Error = SetOptionDataType(
|
|
CommandArgv[2],
|
|
CommandArgv[3],
|
|
&OptionData,
|
|
&UnicodeOptionValueString );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
OptionInfo.DefaultValue.NumElements = 1;
|
|
OptionInfo.DefaultValue.Elements = &OptionData;
|
|
}
|
|
else {
|
|
OptionInfo.DefaultValue.NumElements = 0;
|
|
OptionInfo.DefaultValue.Elements = NULL;
|
|
}
|
|
|
|
OptionInfo.OptionType = DhcpUnaryElementTypeOption;
|
|
Error = DhcpCreateOption(
|
|
GlobalServerIpAddressUnicodeString,
|
|
(DHCP_OPTION_ID)OptionID,
|
|
&OptionInfo );
|
|
|
|
Cleanup:
|
|
if( UnicodeOptionName != NULL ) {
|
|
DhcpFreeMemory( UnicodeOptionName );
|
|
}
|
|
|
|
if( UnicodeOptionValueString != NULL ) {
|
|
DhcpFreeMemory( UnicodeOptionValueString );
|
|
}
|
|
|
|
return( Error );
|
|
|
|
}
|
|
|
|
ProcessSetGlobalOptionValue(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_OPTION_ID OptionID;
|
|
DHCP_OPTION_SCOPE_INFO ScopeInfo;
|
|
DHCP_OPTION_DATA OptionValue;
|
|
DHCP_OPTION_DATA_ELEMENT OptionData;
|
|
LPWSTR UnicodeOptionValueString = NULL;
|
|
|
|
//
|
|
// Expected Parameters are :
|
|
// <OptionID OptionType OptionValue>
|
|
//
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress SetGlobalOptionValue [Command Parameters].\n"
|
|
"<Command Parameters> - <OptionID OptionType OptionValue>.\n");
|
|
Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
|
|
OptionID = strtoul( CommandArgv[0], NULL, 0 );
|
|
if( (OptionID < 0) || (OptionID > 255) ) {
|
|
printf("OptionID too large (%ld).\n", OptionID );
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Error = SetOptionDataType(
|
|
CommandArgv[1],
|
|
CommandArgv[2],
|
|
&OptionData,
|
|
&UnicodeOptionValueString );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
OptionValue.NumElements = 1;
|
|
OptionValue.Elements = &OptionData;
|
|
|
|
ScopeInfo.ScopeType = DhcpGlobalOptions;
|
|
ScopeInfo.ScopeInfo.GlobalScopeInfo = NULL;
|
|
|
|
Error = DhcpSetOptionValue(
|
|
GlobalServerIpAddressUnicodeString,
|
|
(DHCP_OPTION_ID)OptionID,
|
|
&ScopeInfo,
|
|
&OptionValue );
|
|
Cleanup:
|
|
|
|
if( UnicodeOptionValueString != NULL ) {
|
|
DhcpFreeMemory( UnicodeOptionValueString );
|
|
}
|
|
|
|
return( Error );
|
|
}
|
|
|
|
ProcessSetGlobalOptionValues(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
|
|
#define NUM_VALUES 5
|
|
|
|
DWORD Error;
|
|
DHCP_OPTION_ID OptionID;
|
|
DHCP_OPTION_SCOPE_INFO ScopeInfo;
|
|
DHCP_OPTION_DATA OptionValue;
|
|
DHCP_OPTION_DATA_ELEMENT OptionData[NUM_VALUES];
|
|
LPWSTR UnicodeOptionValueString[NUM_VALUES];
|
|
|
|
DHCP_OPTION_VALUE_ARRAY ValuesArray;
|
|
DHCP_OPTION_VALUE Values[NUM_VALUES];
|
|
DWORD NumValue;
|
|
|
|
RtlZeroMemory( UnicodeOptionValueString, NUM_VALUES * sizeof(LPWSTR) );
|
|
//
|
|
// Expected Parameters are :
|
|
// <OptionID OptionType OptionValue>
|
|
//
|
|
|
|
if( CommandArgc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress SetGlobalOptionValues [Command Parameters].\n"
|
|
"<Command Parameters> - <OptionID OptionType OptionValue> <..>.\n"); Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
|
|
for (NumValue = 0;
|
|
(CommandArgc >= 3) && (NumValue < NUM_VALUES);
|
|
NumValue++, CommandArgc -= 3, CommandArgv += 3 ) {
|
|
|
|
OptionID = strtoul( CommandArgv[0], NULL, 0 );
|
|
if( (OptionID < 0) || (OptionID > 255) ) {
|
|
printf("OptionID too large (%ld).\n", OptionID );
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Error = SetOptionDataType(
|
|
CommandArgv[1],
|
|
CommandArgv[2],
|
|
&OptionData[NumValue],
|
|
&UnicodeOptionValueString[NumValue] );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
Values[NumValue].OptionID = OptionID;
|
|
Values[NumValue].Value.NumElements = 1;
|
|
Values[NumValue].Value.Elements = &OptionData[NumValue];
|
|
}
|
|
|
|
ValuesArray.NumElements = NumValue;
|
|
ValuesArray.Values = Values;
|
|
|
|
ScopeInfo.ScopeType = DhcpGlobalOptions;
|
|
ScopeInfo.ScopeInfo.GlobalScopeInfo = NULL;
|
|
|
|
Error = DhcpSetOptionValues(
|
|
GlobalServerIpAddressUnicodeString,
|
|
&ScopeInfo,
|
|
&ValuesArray );
|
|
Cleanup:
|
|
|
|
for (NumValue = 0; NumValue < NUM_VALUES; NumValue++) {
|
|
|
|
if( UnicodeOptionValueString[NumValue] != NULL ) {
|
|
DhcpFreeMemory( UnicodeOptionValueString );
|
|
}
|
|
}
|
|
|
|
return( Error );
|
|
}
|
|
|
|
ProcessSetSubnetOptionValue(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_OPTION_ID OptionID;
|
|
DHCP_OPTION_SCOPE_INFO ScopeInfo;
|
|
DHCP_OPTION_DATA OptionValue;
|
|
DHCP_OPTION_DATA_ELEMENT OptionData;
|
|
LPWSTR UnicodeOptionValueString = NULL;
|
|
|
|
//
|
|
// Expected Parameters are :
|
|
// <OptionID OptionType OptionValue>
|
|
//
|
|
|
|
if( CommandArgc < 4 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress SetSubnetOptionValue "
|
|
"[Command Parameters].\n"
|
|
"<Command Parameters> - "
|
|
"<SubnetAddress OptionID OptionType OptionValue>.\n");
|
|
Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
|
|
ScopeInfo.ScopeType = DhcpSubnetOptions;
|
|
ScopeInfo.ScopeInfo.SubnetScopeInfo =
|
|
DhcpDottedStringToIpAddress( CommandArgv[0] );
|
|
|
|
OptionID = strtoul( CommandArgv[0], NULL, 0 );
|
|
if( (OptionID < 0) || (OptionID > 255) ) {
|
|
printf("OptionID too large (%ld).\n", OptionID );
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
Error = SetOptionDataType(
|
|
CommandArgv[2],
|
|
CommandArgv[3],
|
|
&OptionData,
|
|
&UnicodeOptionValueString );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
OptionValue.NumElements = 1;
|
|
OptionValue.Elements = &OptionData;
|
|
|
|
Error = DhcpSetOptionValue(
|
|
GlobalServerIpAddressUnicodeString,
|
|
(DHCP_OPTION_ID)OptionID,
|
|
&ScopeInfo,
|
|
&OptionValue );
|
|
Cleanup:
|
|
|
|
if( UnicodeOptionValueString != NULL ) {
|
|
DhcpFreeMemory( UnicodeOptionValueString );
|
|
}
|
|
|
|
return( Error );
|
|
}
|
|
|
|
ProcessSetReservedOptionValue(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
printf("This command is not implemented yet !\n");
|
|
return( ERROR_CALL_NOT_IMPLEMENTED );
|
|
}
|
|
|
|
#endif // 0
|
|
|
|
VOID
|
|
PrintClientInfo(
|
|
LPDHCP_CLIENT_INFO_V4 ClientInfo
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD DataLength;
|
|
LPBYTE Data;
|
|
SYSTEMTIME SystemTime;
|
|
FILETIME LocalTime;
|
|
char *szClientType;
|
|
|
|
printf("ClientInfo :\n");
|
|
printf("\tIP Address = %s.\n",
|
|
DhcpIpAddressToDottedString(ClientInfo->ClientIpAddress));
|
|
printf("\tSubnetMask = %s.\n",
|
|
DhcpIpAddressToDottedString(ClientInfo->SubnetMask));
|
|
|
|
DataLength = ClientInfo->ClientHardwareAddress.DataLength;
|
|
Data = ClientInfo->ClientHardwareAddress.Data;
|
|
printf("\tClient Hardware Address = ");
|
|
for( i = 0; i < DataLength; i++ ) {
|
|
if( (i+1) < DataLength ) {
|
|
printf("%.2lx-", (DWORD)Data[i]);
|
|
}
|
|
else {
|
|
printf("%.2lx", (DWORD)Data[i]);
|
|
}
|
|
}
|
|
printf(".\n");
|
|
|
|
printf("\tName = %ws.\n", ClientInfo->ClientName);
|
|
printf("\tComment = %ws.\n", ClientInfo->ClientComment);
|
|
printf("\tType = " );
|
|
|
|
switch( ClientInfo->bClientType )
|
|
{
|
|
case CLIENT_TYPE_NONE:
|
|
szClientType= "None";
|
|
break;
|
|
|
|
case CLIENT_TYPE_DHCP:
|
|
szClientType = "DHCP";
|
|
break;
|
|
|
|
case CLIENT_TYPE_BOOTP:
|
|
szClientType = "BOOTP";
|
|
break;
|
|
|
|
case CLIENT_TYPE_UNSPECIFIED:
|
|
szClientType = "Unspecified";
|
|
break;
|
|
|
|
default:
|
|
DhcpAssert( FALSE );
|
|
}
|
|
printf( "%s\n", szClientType );
|
|
|
|
printf("\tExpires = ");
|
|
|
|
if ( ClientInfo->ClientLeaseExpires.dwLowDateTime ==
|
|
DHCP_DATE_TIME_INFINIT_LOW &&
|
|
ClientInfo->ClientLeaseExpires.dwHighDateTime ==
|
|
DHCP_DATE_TIME_INFINIT_HIGH )
|
|
{
|
|
printf( "Never (lease duration is infinite.)\n" );
|
|
}
|
|
else if( FileTimeToLocalFileTime(
|
|
(FILETIME *)(&ClientInfo->ClientLeaseExpires),
|
|
&LocalTime) ) {
|
|
|
|
if( FileTimeToSystemTime( &LocalTime, &SystemTime ) ) {
|
|
|
|
printf( "%02u/%02u/%02u %02u:%02u:%02u.\n",
|
|
SystemTime.wMonth,
|
|
SystemTime.wDay,
|
|
SystemTime.wYear,
|
|
SystemTime.wHour,
|
|
SystemTime.wMinute,
|
|
SystemTime.wSecond );
|
|
}
|
|
else {
|
|
printf( "Can't convert time, %ld.\n", GetLastError() );
|
|
}
|
|
}
|
|
else {
|
|
printf( "Can't convert time, %ld.\n", GetLastError() );
|
|
}
|
|
|
|
printf("\tOwner Host IP Address = %s.\n",
|
|
DhcpIpAddressToDottedString(ClientInfo->OwnerHost.IpAddress));
|
|
printf("\tOwner Host NetBios Name = %ws.\n",
|
|
ClientInfo->OwnerHost.NetBiosName );
|
|
printf("\tOwner Host Name = %ws.\n",
|
|
ClientInfo->OwnerHost.HostName );
|
|
|
|
}
|
|
|
|
VOID
|
|
PrintClientInfoShort(
|
|
LPDHCP_CLIENT_INFO_V4 ClientInfo
|
|
)
|
|
{
|
|
SYSTEMTIME SystemTime;
|
|
FILETIME LocalTime;
|
|
|
|
printf("%ld\t %- 16.16s %- 16.16ws ",
|
|
GlobalClientCount++,
|
|
DhcpIpAddressToDottedString(ClientInfo->ClientIpAddress),
|
|
ClientInfo->ClientName
|
|
);
|
|
if ( ClientInfo->ClientLeaseExpires.dwLowDateTime ==
|
|
DHCP_DATE_TIME_INFINIT_LOW &&
|
|
ClientInfo->ClientLeaseExpires.dwHighDateTime ==
|
|
DHCP_DATE_TIME_INFINIT_HIGH )
|
|
{
|
|
printf( "Never (lease duration is infinite.)\n" );
|
|
}
|
|
else if( FileTimeToLocalFileTime(
|
|
(FILETIME *)(&ClientInfo->ClientLeaseExpires),
|
|
&LocalTime) ) {
|
|
|
|
if( FileTimeToSystemTime( &LocalTime, &SystemTime ) ) {
|
|
|
|
printf( "%02u/%02u/%02u %02u:%02u:%02u",
|
|
SystemTime.wMonth,
|
|
SystemTime.wDay,
|
|
SystemTime.wYear,
|
|
SystemTime.wHour,
|
|
SystemTime.wMinute,
|
|
SystemTime.wSecond );
|
|
}
|
|
else {
|
|
printf( "% 18.18s", "******************" );
|
|
}
|
|
}
|
|
else {
|
|
printf( "%.18s", "******************" );
|
|
}
|
|
|
|
printf( "\n" );
|
|
}
|
|
|
|
VOID
|
|
PrintClientInfoShort1(
|
|
LPDHCP_CLIENT_INFO_V4 ClientInfo
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD DataLength;
|
|
LPBYTE Data;
|
|
|
|
printf("%ld\t %- 16.16s %- 16.16ws ",
|
|
GlobalClientCount++,
|
|
DhcpIpAddressToDottedString(ClientInfo->ClientIpAddress),
|
|
ClientInfo->ClientName
|
|
);
|
|
|
|
DataLength = ClientInfo->ClientHardwareAddress.DataLength;
|
|
Data = ClientInfo->ClientHardwareAddress.Data;
|
|
for( i = 0; i < DataLength; i++ ) {
|
|
printf("%.2lx", (DWORD)Data[i]);
|
|
}
|
|
|
|
printf( "\n" );
|
|
}
|
|
|
|
DWORD
|
|
ProcessEnumClients(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
DHCP_RESUME_HANDLE ResumeHandle = 0;
|
|
LPDHCP_CLIENT_INFO_ARRAY_V4 ClientEnumInfo = NULL;
|
|
DWORD ClientsRead = 0;
|
|
DWORD ClientsTotal = 0;
|
|
DWORD i;
|
|
|
|
//
|
|
// Expected Parameters are : <SubnetAddress>
|
|
//
|
|
|
|
|
|
if( CommandArgc < 1 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress EnumClients [Command Parameters].\n"
|
|
"<Command Parameters> - <SubnetAddress [-v | -h] >.\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
GlobalClientCount = 1;
|
|
|
|
for(;;) {
|
|
|
|
Error = DhcpEnumSubnetClientsV4(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
&ResumeHandle,
|
|
(DWORD)(-1),
|
|
&ClientEnumInfo,
|
|
&ClientsRead,
|
|
&ClientsTotal );
|
|
|
|
if( (Error != ERROR_SUCCESS) && (Error != ERROR_MORE_DATA) ) {
|
|
printf("DhcpEnumSubnetClients failed, %ld.\n", Error );
|
|
return( Error );
|
|
}
|
|
|
|
DhcpAssert( ClientEnumInfo != NULL );
|
|
DhcpAssert( ClientEnumInfo->NumElements == ClientsRead );
|
|
|
|
if( (CommandArgc > 1) && CommandArgv[1][0] == '-') {
|
|
|
|
switch (CommandArgv[1][1]) {
|
|
case 'h':
|
|
case 'H':
|
|
for( i = 0; i < ClientsRead; i++ ) {
|
|
PrintClientInfoShort1( ClientEnumInfo->Clients[i] );
|
|
}
|
|
break;
|
|
|
|
case 'V':
|
|
case 'v':
|
|
printf("Num Client info read = %ld.\n", ClientsRead );
|
|
printf("Total Client count = %ld.\n", ClientsTotal );
|
|
|
|
for( i = 0; i < ClientsRead; i++ ) {
|
|
PrintClientInfo( ClientEnumInfo->Clients[i] );
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
for( i = 0; i < ClientsRead; i++ ) {
|
|
PrintClientInfoShort( ClientEnumInfo->Clients[i] );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
|
|
for( i = 0; i < ClientsRead; i++ ) {
|
|
PrintClientInfoShort( ClientEnumInfo->Clients[i] );
|
|
}
|
|
}
|
|
|
|
DhcpRpcFreeMemory( ClientEnumInfo );
|
|
|
|
if( Error != ERROR_MORE_DATA ) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(Error);
|
|
}
|
|
|
|
|
|
DWORD
|
|
ProcessMibCounts(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
LPDHCP_MIB_INFO MibInfo = NULL;
|
|
DWORD i;
|
|
LPSCOPE_MIB_INFO ScopeInfo;
|
|
SYSTEMTIME SystemTime;
|
|
FILETIME LocalTime;
|
|
|
|
Error = DhcpGetMibInfo(
|
|
GlobalServerIpAddressUnicodeString,
|
|
&MibInfo );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
return( Error );
|
|
}
|
|
|
|
DhcpAssert( MibInfo != NULL );
|
|
|
|
printf("Discovers = %d.\n", MibInfo->Discovers);
|
|
printf("Offers = %d.\n", MibInfo->Offers);
|
|
printf("Requests = %d.\n", MibInfo->Requests);
|
|
printf("Acks = %d.\n", MibInfo->Acks);
|
|
printf("Naks = %d.\n", MibInfo->Naks);
|
|
printf("Declines = %d.\n", MibInfo->Declines);
|
|
printf("Releases = %d.\n", MibInfo->Releases);
|
|
printf("ServerStartTime = ");
|
|
|
|
if( FileTimeToLocalFileTime(
|
|
(FILETIME *)(&MibInfo->ServerStartTime),
|
|
&LocalTime) ) {
|
|
|
|
if( FileTimeToSystemTime( &LocalTime, &SystemTime ) ) {
|
|
|
|
printf( "%02u/%02u/%02u %02u:%02u:%02u.\n",
|
|
SystemTime.wMonth,
|
|
SystemTime.wDay,
|
|
SystemTime.wYear,
|
|
SystemTime.wHour,
|
|
SystemTime.wMinute,
|
|
SystemTime.wSecond );
|
|
}
|
|
else {
|
|
printf( "Can't convert time, %ld.\n", GetLastError() );
|
|
}
|
|
}
|
|
else {
|
|
printf( "Can't convert time, %ld.\n", GetLastError() );
|
|
}
|
|
|
|
printf("Scopes = %d.\n", MibInfo->Scopes);
|
|
|
|
ScopeInfo = MibInfo->ScopeInfo;
|
|
|
|
for ( i = 0; i < MibInfo->Scopes; i++ ) {
|
|
printf("Subnet = %s.\n",
|
|
DhcpIpAddressToDottedString(ScopeInfo[i].Subnet));
|
|
printf("\tNumAddressesInuse = %d.\n",
|
|
ScopeInfo[i].NumAddressesInuse );
|
|
printf("\tNumAddressesFree = %d.\n",
|
|
ScopeInfo[i].NumAddressesFree );
|
|
printf("\tNumPendingOffers = %d.\n",
|
|
ScopeInfo[i].NumPendingOffers );
|
|
}
|
|
|
|
DhcpRpcFreeMemory( MibInfo );
|
|
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
VOID
|
|
PrintConfigCommands(
|
|
VOID
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD NumCommands;
|
|
|
|
NumCommands = sizeof(GlobalConfigCommandInfo) /
|
|
sizeof(CONFIG_COMMAND_INFO);
|
|
|
|
DhcpAssert( NumCommands <= UnknownConfigCommand );
|
|
for( i = 0; i < NumCommands; i++) {
|
|
printf( "\t%ld. %s\n",
|
|
i, GlobalConfigCommandInfo[i].CommandName );
|
|
}
|
|
}
|
|
|
|
CONFIG_COMMAND_CODE
|
|
DecodeConfigCommand(
|
|
LPSTR CommandName
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD NumCommands;
|
|
|
|
NumCommands = sizeof(GlobalConfigCommandInfo) /
|
|
sizeof(CONFIG_COMMAND_INFO);
|
|
|
|
DhcpAssert( NumCommands <= UnknownConfigCommand );
|
|
for( i = 0; i < NumCommands; i++) {
|
|
if( _stricmp( CommandName,
|
|
GlobalConfigCommandInfo[i].CommandName ) == 0 ) {
|
|
return( GlobalConfigCommandInfo[i].CommandCode );
|
|
}
|
|
}
|
|
return( UnknownConfigCommand );
|
|
}
|
|
|
|
//
|
|
// this function assumes input of the following format:
|
|
//
|
|
// [generic name1],[server name1],<boot file1>;[generic name2],...
|
|
//
|
|
//
|
|
|
|
|
|
WCHAR *
|
|
ParseBootFileTable(
|
|
char *szBootFileTable,
|
|
DWORD *pcb
|
|
)
|
|
{
|
|
WCHAR *pwszOutput;
|
|
DWORD cb;
|
|
|
|
*pcb = 0;
|
|
cb = strlen( szBootFileTable ) + 2; // double null terminator
|
|
|
|
pwszOutput = DhcpAllocateMemory( cb * sizeof( WCHAR ) );
|
|
if ( pwszOutput )
|
|
{
|
|
WCHAR *pwszTemp = DhcpOemToUnicode( szBootFileTable, pwszOutput );
|
|
|
|
if ( !pwszTemp )
|
|
{
|
|
// conversion failed
|
|
DhcpFreeMemory( pwszOutput );
|
|
pwszOutput = NULL;
|
|
}
|
|
else
|
|
{
|
|
// replace ';' with '\0'
|
|
while ( *pwszTemp )
|
|
{
|
|
if ( L';' == *pwszTemp )
|
|
{
|
|
*pwszTemp = L'\0';
|
|
}
|
|
|
|
++pwszTemp;
|
|
}
|
|
|
|
*pcb = cb * sizeof( WCHAR );
|
|
|
|
// add 2cnd null terminator
|
|
pwszOutput[ cb - 1 ] = L'\0';
|
|
}
|
|
|
|
}
|
|
|
|
return pwszOutput;
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintBootFileString(
|
|
WCHAR *wszBootFileString
|
|
)
|
|
{
|
|
WCHAR *pwszBootFile = wszBootFileString;
|
|
|
|
while( *pwszBootFile != BOOT_FILE_STRING_DELIMITER_W )
|
|
pwszBootFile++;
|
|
|
|
*pwszBootFile = L'\0';
|
|
|
|
printf( "Bootfile Server = %S\n", wszBootFileString );
|
|
printf( "Bootfile = %S\n\n", ++pwszBootFile );
|
|
}
|
|
|
|
void PrintBootTableString(
|
|
WCHAR *wszBootFileTable
|
|
)
|
|
{
|
|
while( *wszBootFileTable )
|
|
{
|
|
WCHAR *pwszDelimiter = wszBootFileTable;
|
|
DWORD cb = wcslen( wszBootFileTable ) + 1;
|
|
|
|
while( *pwszDelimiter != BOOT_FILE_STRING_DELIMITER_W )
|
|
pwszDelimiter++;
|
|
|
|
*pwszDelimiter = L'\0';
|
|
printf( "Generic Bootfile request = %S\n", wszBootFileTable );
|
|
PrintBootFileString( ++pwszDelimiter );
|
|
|
|
wszBootFileTable += cb;
|
|
}
|
|
}
|
|
|
|
DWORD ProcessRemoveSubscope(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DHCP_IP_ADDRESS SubnetAddress;
|
|
DWORD dwResult;
|
|
|
|
if( CommandArgc < 1 )
|
|
{
|
|
printf("usage:DhcpCmd SrvIpAddress RemoveSubscope <scope ID>.\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
SubnetAddress = htonl( inet_addr( CommandArgv[0] ) );
|
|
|
|
dwResult = DhcpSetSuperScopeV4( GlobalServerIpAddressUnicodeString,
|
|
SubnetAddress,
|
|
NULL,
|
|
TRUE );
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD ProcessSetSuperScope(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DHCP_IP_ADDRESS SubnetAddress;
|
|
WCHAR *pwszSuperScopeName;
|
|
BOOL fChangeExisting;
|
|
DWORD dwResult;
|
|
|
|
if( CommandArgc < 3 )
|
|
{
|
|
printf("usage:DhcpCmd SrvIpAddress SetSuperScope <SuperScope name> <scope ID> <1|0>\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
pwszSuperScopeName = DhcpOemToUnicode( CommandArgv[0], NULL );
|
|
SubnetAddress = htonl( inet_addr( CommandArgv[1] ) );
|
|
fChangeExisting = (BOOL) ( *(CommandArgv[2]) - '0' );
|
|
|
|
dwResult = DhcpSetSuperScopeV4( GlobalServerIpAddressUnicodeString,
|
|
SubnetAddress,
|
|
pwszSuperScopeName,
|
|
fChangeExisting );
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD ProcessDeleteSuperScope(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
WCHAR *pwszSuperScope;
|
|
DWORD dwResult;
|
|
|
|
if( CommandArgc < 1 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress DeleteSuperScope <scope name>.\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
printf( "Deleting SuperScope %s\n", CommandArgv[0] );
|
|
|
|
pwszSuperScope = DhcpOemToUnicode( CommandArgv[0], NULL );
|
|
dwResult = DhcpDeleteSuperScopeV4( GlobalServerIpAddressUnicodeString,
|
|
pwszSuperScope );
|
|
|
|
DhcpFreeMemory( pwszSuperScope );
|
|
|
|
return dwResult;
|
|
}
|
|
|
|
DWORD ProcessGetSuperScopeTable(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DHCP_SUPER_SCOPE_TABLE *pTable = NULL;
|
|
DWORD dwResult;
|
|
|
|
dwResult = DhcpGetSuperScopeInfoV4(
|
|
GlobalServerIpAddressUnicodeString,
|
|
&pTable );
|
|
if ( ERROR_SUCCESS == dwResult )
|
|
{
|
|
DWORD n;
|
|
|
|
for ( n = 0; n < pTable->cEntries; n++ )
|
|
{
|
|
IN_ADDR InAddr;
|
|
|
|
InAddr.s_addr = htonl( pTable->pEntries[n].SubnetAddress );
|
|
|
|
printf( "Superscope name = %S\n", pTable->pEntries[n].SuperScopeName );
|
|
printf( "Subnet address = %s\n", inet_ntoa( InAddr ) );
|
|
printf( "Superscope goup number = %d\n", pTable->pEntries[n].SuperScopeNumber );
|
|
}
|
|
|
|
|
|
DhcpRpcFreeMemory( pTable );
|
|
}
|
|
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD
|
|
ProcessServerConfig(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
LPDHCP_SERVER_CONFIG_INFO_V4 ConfigInfo = NULL;
|
|
DWORD FieldsToSet = 0;
|
|
CONFIG_COMMAND_CODE CommandCode;
|
|
DWORD Value;
|
|
LPWSTR ValueString;
|
|
|
|
if( CommandArgc < 1 ) {
|
|
|
|
Error = DhcpServerGetConfigV4(
|
|
GlobalServerIpAddressUnicodeString,
|
|
&ConfigInfo );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
return( Error );
|
|
}
|
|
|
|
DhcpAssert( ConfigInfo != NULL );
|
|
|
|
printf("APIProtocolSupport = %lx\n", ConfigInfo->APIProtocolSupport );
|
|
printf("DatabaseName = %ws\n", ConfigInfo->DatabaseName );
|
|
printf("DatabasePath = %ws\n", ConfigInfo->DatabasePath );
|
|
printf("BackupPath = %ws\n", ConfigInfo->BackupPath );
|
|
printf("BackupInterval = %ld mins.\n",
|
|
ConfigInfo->BackupInterval );
|
|
printf("DatabaseLoggingFlag = %ld\n", ConfigInfo->DatabaseLoggingFlag );
|
|
printf("RestoreFlag = %ld\n", ConfigInfo->RestoreFlag );
|
|
printf("DatabaseCleanupInterval = %ld mins.\n",
|
|
ConfigInfo->DatabaseCleanupInterval );
|
|
printf("DebugFlag = %lx\n", ConfigInfo->DebugFlag );
|
|
printf("PingRetries = %d\n", ConfigInfo->dwPingRetries );
|
|
printf("ActivityLog = %d\n", (DWORD) ConfigInfo->fAuditLog );
|
|
|
|
if ( ConfigInfo->cbBootTableString )
|
|
{
|
|
printf( "BOOTP request table:\n" );
|
|
PrintBootTableString( ConfigInfo->wszBootTableString );
|
|
}
|
|
|
|
DhcpRpcFreeMemory( ConfigInfo );
|
|
|
|
return( Error );
|
|
}
|
|
|
|
|
|
if ( CommandArgc == 1)
|
|
{
|
|
++CommandArgc;
|
|
}
|
|
else
|
|
{
|
|
ConfigInfo = DhcpAllocateMemory( sizeof(DHCP_SERVER_CONFIG_INFO_V4) );
|
|
|
|
if( ConfigInfo == NULL ) {
|
|
printf("Insufficient memory\n");
|
|
return( ERROR_NOT_ENOUGH_MEMORY );
|
|
}
|
|
|
|
RtlZeroMemory( ConfigInfo, sizeof( *ConfigInfo ) );
|
|
}
|
|
while( CommandArgc >= 2 ) {
|
|
|
|
|
|
CommandCode = DecodeConfigCommand( CommandArgv[0] );
|
|
|
|
Value = 0;
|
|
ValueString = NULL;
|
|
|
|
switch( CommandCode )
|
|
{
|
|
case ConfigDatabaseName:
|
|
case ConfigDatabasePath:
|
|
case ConfigBackupPath:
|
|
case ConfigAPIProtocolSupport:
|
|
case ConfigBackupInterval:
|
|
case ConfigDatabaseLoggingFlag:
|
|
case ConfigRestoreFlag:
|
|
case ConfigDatabaseCleanupInterval:
|
|
case ConfigDebugFlag:
|
|
case ConfigActivityLog:
|
|
case ConfigPingRetries:
|
|
Value = atoi( CommandArgv[1] );
|
|
break;
|
|
|
|
case ConfigBootFileTable:
|
|
ValueString = ParseBootFileTable( CommandArgv[1],
|
|
&Value );
|
|
break;
|
|
}
|
|
|
|
|
|
switch( CommandCode ) {
|
|
case ConfigAPIProtocolSupport:
|
|
FieldsToSet |= Set_APIProtocolSupport;
|
|
ConfigInfo->APIProtocolSupport = Value;
|
|
break;
|
|
|
|
case ConfigDatabaseName:
|
|
FieldsToSet |= Set_DatabaseName;
|
|
ConfigInfo->DatabaseName = ValueString;
|
|
break;
|
|
|
|
case ConfigDatabasePath:
|
|
FieldsToSet |= Set_DatabasePath;
|
|
ConfigInfo->DatabasePath = ValueString;
|
|
break;
|
|
|
|
case ConfigBackupPath:
|
|
FieldsToSet |= Set_BackupPath;
|
|
ConfigInfo->BackupPath = ValueString;
|
|
break;
|
|
|
|
case ConfigBackupInterval:
|
|
FieldsToSet |= Set_BackupInterval;
|
|
ConfigInfo->BackupInterval = Value;
|
|
break;
|
|
|
|
case ConfigDatabaseLoggingFlag:
|
|
FieldsToSet |= Set_DatabaseLoggingFlag;
|
|
ConfigInfo->DatabaseLoggingFlag = Value;
|
|
break;
|
|
|
|
case ConfigRestoreFlag:
|
|
FieldsToSet |= Set_RestoreFlag;
|
|
ConfigInfo->RestoreFlag = Value;
|
|
break;
|
|
|
|
case ConfigDatabaseCleanupInterval:
|
|
FieldsToSet |= Set_DatabaseCleanupInterval;
|
|
ConfigInfo->DatabaseCleanupInterval = Value;
|
|
break;
|
|
|
|
case ConfigDebugFlag:
|
|
FieldsToSet |= Set_DebugFlag;
|
|
ConfigInfo->DebugFlag = Value;
|
|
break;
|
|
|
|
|
|
case ConfigPingRetries:
|
|
FieldsToSet |= Set_PingRetries;
|
|
ConfigInfo->dwPingRetries = Value;
|
|
break;
|
|
|
|
case ConfigActivityLog:
|
|
FieldsToSet |= Set_AuditLogState;
|
|
ConfigInfo->fAuditLog = (BOOL) Value;
|
|
break;
|
|
|
|
case ConfigBootFileTable:
|
|
|
|
FieldsToSet |= Set_BootFileTable;
|
|
ConfigInfo->wszBootTableString = ValueString;
|
|
ConfigInfo->cbBootTableString = Value;
|
|
|
|
break;
|
|
|
|
case UnknownConfigCommand:
|
|
default:
|
|
printf("usage:DhcpCmd SrvIpAddress ServerConfig "
|
|
"[ConfigCommand ConfigValue]"
|
|
"[ConfigCommand ConfigValue]"
|
|
"... \n");
|
|
|
|
printf("ConfigCommands : \n");
|
|
PrintConfigCommands();
|
|
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
CommandArgc -= 2;
|
|
CommandArgv += 2;
|
|
}
|
|
|
|
Error = DhcpServerSetConfigV4(
|
|
GlobalServerIpAddressUnicodeString,
|
|
FieldsToSet,
|
|
ConfigInfo );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
Error = ProcessServerConfig( 0, NULL );
|
|
|
|
Cleanup:
|
|
|
|
if( ConfigInfo != NULL ) {
|
|
|
|
if( ConfigInfo->DatabaseName != NULL ) {
|
|
DhcpFreeMemory( ConfigInfo->DatabaseName );
|
|
}
|
|
|
|
if( ConfigInfo->DatabasePath != NULL ) {
|
|
DhcpFreeMemory( ConfigInfo->DatabasePath );
|
|
}
|
|
|
|
if( ConfigInfo->BackupPath != NULL ) {
|
|
DhcpFreeMemory( ConfigInfo->BackupPath );
|
|
}
|
|
|
|
DhcpFreeMemory( ConfigInfo );
|
|
}
|
|
|
|
return( Error );
|
|
}
|
|
|
|
#if 0
|
|
|
|
DWORD
|
|
ProcessCheckDB(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
LPDHCP_SCAN_LIST ScanList = NULL;
|
|
BOOL FixFlag = FALSE;
|
|
|
|
if( CommandArgc < 1 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress CheckDB [Command Parameters].\n"
|
|
"<Command Parameters> - <SubnetAddress> <[Fix]>.\n" );
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
if( CommandArgc >= 2 ) {
|
|
|
|
//
|
|
// parse fix parameter.
|
|
//
|
|
|
|
if( _stricmp(CommandArgv[0], "fix") ) {
|
|
FixFlag = TRUE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// scan dhcp database and registry, check consistency and get bad
|
|
// entries if any.
|
|
//
|
|
|
|
Error = DhcpScanDatabase(
|
|
GlobalServerIpAddressUnicodeString,
|
|
DhcpDottedStringToIpAddress(CommandArgv[0]),
|
|
FixFlag,
|
|
&ScanList
|
|
);
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
printf("DhcpScanDatabase failed, %ld.\n", Error );
|
|
return( Error );
|
|
}
|
|
|
|
//
|
|
// display bad entries.
|
|
//
|
|
|
|
if( (ScanList != NULL) &&
|
|
(ScanList->NumScanItems != 0) &&
|
|
(ScanList->ScanItems != NULL) ) {
|
|
|
|
LPDHCP_SCAN_ITEM ScanItem;
|
|
LPDHCP_SCAN_ITEM ScanItemEnd;
|
|
DWORD i = 1;
|
|
|
|
ScanItemEnd =
|
|
ScanList->ScanItems +
|
|
ScanList->NumScanItems;
|
|
|
|
for( ScanItem = ScanList->ScanItems;
|
|
ScanItem < ScanItemEnd; ScanItem++ ) {
|
|
|
|
printf("%ld %- 16.16s ",
|
|
i++,
|
|
DhcpIpAddressToDottedString(ScanItem->IpAddress) );
|
|
|
|
if( ScanItem->ScanFlag == DhcpRegistryFix ) {
|
|
printf("Fix Registry\n");
|
|
}
|
|
else if( ScanItem->ScanFlag == DhcpDatabaseFix ) {
|
|
printf("Fix Database\n");
|
|
}
|
|
else {
|
|
printf("Fix Unknown\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return( ERROR_SUCCESS );
|
|
}
|
|
|
|
VOID
|
|
PrintOptionValue(
|
|
LPDHCP_OPTION_DATA OptionValue
|
|
)
|
|
{
|
|
DWORD NumElements;
|
|
DHCP_OPTION_DATA_TYPE OptionType;
|
|
DWORD i;
|
|
|
|
printf("Option Value : \n");
|
|
NumElements = OptionValue->NumElements;
|
|
|
|
printf("\tNumber of Option Elements = %ld\n", NumElements );
|
|
|
|
if( NumElements == 0 ) {
|
|
return;
|
|
}
|
|
|
|
OptionType = OptionValue->Elements[0].OptionType;
|
|
printf("\tOption Elements Type = " );
|
|
|
|
switch( OptionType ) {
|
|
case DhcpByteOption:
|
|
printf("DhcpByteOption\n");
|
|
break;
|
|
|
|
case DhcpWordOption:
|
|
printf("DhcpWordOption\n");
|
|
break;
|
|
|
|
case DhcpDWordOption:
|
|
printf("DhcpDWordOption\n");
|
|
break;
|
|
|
|
case DhcpDWordDWordOption:
|
|
printf("DhcpDWordDWordOption\n");
|
|
break;
|
|
|
|
case DhcpIpAddressOption:
|
|
printf("DhcpIpAddressOption\n");
|
|
break;
|
|
|
|
case DhcpStringDataOption:
|
|
printf("DhcpStringDataOption\n");
|
|
break;
|
|
|
|
case DhcpBinaryDataOption:
|
|
printf("DhcpBinaryDataOption\n");
|
|
break;
|
|
|
|
case DhcpEncapsulatedDataOption:
|
|
printf("DhcpEncapsulatedDataOption\n");
|
|
break;
|
|
default:
|
|
printf("Unknown\n");
|
|
return;
|
|
}
|
|
|
|
for( i = 0; i < OptionValue->NumElements; i++ ) {
|
|
DhcpAssert( OptionType == OptionValue->Elements[i].OptionType );
|
|
printf("Option Element %ld value = ", i );
|
|
|
|
switch( OptionType ) {
|
|
case DhcpByteOption:
|
|
printf("%lx.\n", (DWORD)
|
|
OptionValue->Elements[i].Element.ByteOption );
|
|
break;
|
|
|
|
case DhcpWordOption:
|
|
printf("%lx.\n", (DWORD)
|
|
OptionValue->Elements[i].Element.WordOption );
|
|
break;
|
|
|
|
case DhcpDWordOption:
|
|
printf("%lx.\n",
|
|
OptionValue->Elements[i].Element.DWordOption );
|
|
break;
|
|
|
|
case DhcpDWordDWordOption:
|
|
printf("%lx, %lx.\n",
|
|
OptionValue->Elements[i].Element.DWordDWordOption.DWord1,
|
|
OptionValue->Elements[i].Element.DWordDWordOption.DWord2 );
|
|
|
|
break;
|
|
|
|
case DhcpIpAddressOption:
|
|
printf("%lx.\n",
|
|
OptionValue->Elements[i].Element.IpAddressOption );
|
|
break;
|
|
|
|
case DhcpStringDataOption:
|
|
printf("%ws.\n",
|
|
OptionValue->Elements[i].Element.StringDataOption );
|
|
break;
|
|
|
|
case DhcpBinaryDataOption:
|
|
case DhcpEncapsulatedDataOption: {
|
|
DWORD j;
|
|
DWORD Length;
|
|
|
|
Length = OptionValue->Elements[i].Element.BinaryDataOption.DataLength;
|
|
for( j = 0; j < Length; j++ ) {
|
|
printf("%2lx ",
|
|
OptionValue->Elements[i].Element.BinaryDataOption.Data[j] );
|
|
}
|
|
printf(".\n");
|
|
break;
|
|
}
|
|
default:
|
|
printf("PrintOptionValue: Unknown OptionType.\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
PrintOptionInfo(
|
|
LPDHCP_OPTION OptionInfo
|
|
)
|
|
{
|
|
printf( "Option Info : \n");
|
|
printf( "\tOptionId : %ld \n", (DWORD)OptionInfo->OptionID );
|
|
printf( "\tOptionName : %ws \n", (DWORD)OptionInfo->OptionName );
|
|
printf( "\tOptionComment : %ws \n", (DWORD)OptionInfo->OptionComment );
|
|
PrintOptionValue( &OptionInfo->DefaultValue );
|
|
printf( "\tOptionType : %ld \n", (DWORD)OptionInfo->OptionType );
|
|
}
|
|
|
|
DWORD
|
|
ProcessEnumOptions(
|
|
DWORD CommandArgc,
|
|
LPSTR *CommandArgv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
LPDHCP_OPTION_ARRAY OptionsArray = NULL;
|
|
DHCP_RESUME_HANDLE ResumeHandle = 0;
|
|
DWORD OptionsRead;
|
|
DWORD OptionsTotal;
|
|
|
|
|
|
Error = DhcpEnumOptions(
|
|
GlobalServerIpAddressUnicodeString,
|
|
&ResumeHandle,
|
|
0xFFFFFFFF, // get all.
|
|
&OptionsArray,
|
|
&OptionsRead,
|
|
&OptionsTotal );
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
printf("DhcpEnumOptions failed %ld\n", Error );
|
|
}
|
|
else {
|
|
|
|
DWORD i;
|
|
LPDHCP_OPTION Options;
|
|
DWORD NumOptions;
|
|
|
|
printf("OptionsRead = %ld.\n", OptionsRead);
|
|
printf("OptionsTotal = %ld.\n", OptionsTotal);
|
|
|
|
Options = OptionsArray->Options;
|
|
NumOptions = OptionsArray->NumElements;
|
|
|
|
for( i = 0; i < NumOptions; i++, Options++ ) {
|
|
PrintOptionInfo( Options );
|
|
}
|
|
DhcpRpcFreeMemory( OptionsArray );
|
|
OptionsArray = NULL;
|
|
}
|
|
|
|
return( Error );
|
|
}
|
|
|
|
#endif // 0
|
|
|
|
DWORD
|
|
ProcessGetVersion(
|
|
DWORD *pdwMajor,
|
|
DWORD *pdwMinor
|
|
)
|
|
{
|
|
DWORD Error = ERROR_SUCCESS;
|
|
DWORD MajorVersion;
|
|
DWORD MinorVersion;
|
|
|
|
if ( g_dwMajor == (DWORD) -1 && g_dwMinor == (DWORD) -1 )
|
|
{
|
|
|
|
Error = DhcpGetVersion( GlobalServerIpAddressUnicodeString,
|
|
&g_dwMajor,
|
|
&g_dwMinor );
|
|
|
|
if ( ERROR_SUCCESS == Error )
|
|
{
|
|
printf( "DHCP Server version %d.%d\n", g_dwMajor, g_dwMinor );
|
|
}
|
|
|
|
}
|
|
|
|
return Error;
|
|
|
|
}
|
|
|
|
DWORD _CRTAPI1
|
|
main(
|
|
int argc,
|
|
char **argv
|
|
)
|
|
{
|
|
DWORD Error;
|
|
COMMAND_CODE CommandCode;
|
|
DWORD CommandArgc;
|
|
LPSTR *CommandArgv;
|
|
|
|
INIT_DEBUG_HEAP( HEAPX_VERIFY );
|
|
|
|
if( argc < 3 ) {
|
|
printf("usage:DhcpCmd SrvIpAddress Command [Command Parameters].\n");
|
|
printf("Commands : \n");
|
|
PrintCommands();
|
|
Error = ERROR_SUCCESS;
|
|
goto Cleanup;
|
|
}
|
|
|
|
GlobalServerIpAddressAnsiString = argv[1];
|
|
GlobalServerIpAddressUnicodeString =
|
|
DhcpOemToUnicode( GlobalServerIpAddressAnsiString, NULL );
|
|
|
|
if( GlobalServerIpAddressUnicodeString == NULL ) {
|
|
Error = ERROR_NOT_ENOUGH_MEMORY;
|
|
printf("Insufficient memory\n");
|
|
goto Cleanup;
|
|
}
|
|
|
|
GlobalServerIpAddressAnsiString = argv[1];
|
|
|
|
CommandCode = DecodeCommand( argv[2] );
|
|
if( CommandCode == UnknownCommand ) {
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
printf("Unknown Command Specified.\n");
|
|
goto Cleanup;
|
|
}
|
|
|
|
Error = ProcessGetVersion( &g_dwMajor, &g_dwMinor );
|
|
if ( ERROR_SUCCESS != Error )
|
|
{
|
|
printf("Unable to determine server version.\n" );
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ( !IsValidServerVersion( g_dwMajor, g_dwMinor ) )
|
|
{
|
|
printf( "This version of %s works with Microsoft DHCP server running on \
|
|
Windows NT Server version %d.%d or later.\n",
|
|
argv[0],
|
|
DHCPCMD_VERSION_MAJOR,
|
|
DHCPCMD_VERSION_MINOR );
|
|
Error = ERROR_OLD_WIN_VERSION;
|
|
goto Cleanup;
|
|
}
|
|
|
|
CommandArgc = (DWORD)(argc - 3);
|
|
CommandArgv = &argv[3];
|
|
|
|
switch( CommandCode ) {
|
|
case AddIpRange:
|
|
Error = ProcessAddIpRange( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case AddReservedIp:
|
|
Error = ProcessAddReservedIp( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case EnumClients:
|
|
Error = ProcessEnumClients( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case MibCounts:
|
|
Error = ProcessMibCounts( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case ServerConfig:
|
|
Error = ProcessServerConfig( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case GetDhcpVersion:
|
|
Error = ProcessGetVersion( &g_dwMajor, &g_dwMinor );
|
|
break;
|
|
|
|
case SetSuperScope:
|
|
Error = ProcessSetSuperScope( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case RemoveSubscope:
|
|
Error = ProcessRemoveSubscope( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case DeleteSuperScope:
|
|
Error = ProcessDeleteSuperScope( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case GetSuperScopeTable:
|
|
Error = ProcessGetSuperScopeTable( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
#if 0
|
|
case CheckDB:
|
|
Error = ProcessCheckDB( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case CreateSubnet:
|
|
Error = ProcessCreateSubnet( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case AddExcludeRange:
|
|
Error = ProcessAddExcludeRange( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case RemoveReservedIp:
|
|
Error = ProcessRemoveReservedIp( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case RemoveExcludeRange:
|
|
Error = ProcessRemoveExcludeRange( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case SetSubnetState:
|
|
Error = ProcessSetSubnetState( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case DeleteSubnet:
|
|
Error = ProcessDeleteSubnet( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case CreateOption:
|
|
Error = ProcessCreateOption( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case SetGlobalOptionValue:
|
|
Error = ProcessSetGlobalOptionValue( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case SetGlobalOptionValues:
|
|
Error = ProcessSetGlobalOptionValues( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case SetSubnetOptionValue:
|
|
Error = ProcessSetSubnetOptionValue( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case SetReservedOptionValue:
|
|
Error = ProcessSetReservedOptionValue( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
case EnumOptions:
|
|
Error = ProcessEnumOptions( CommandArgc, CommandArgv );
|
|
break;
|
|
|
|
#endif // 0
|
|
|
|
case UnknownCommand:
|
|
default:
|
|
DhcpAssert( FALSE );
|
|
Error = ERROR_INVALID_PARAMETER;
|
|
printf("Unknown Command Specified.\n");
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if( GlobalServerIpAddressUnicodeString != NULL ) {
|
|
DhcpFreeMemory( GlobalServerIpAddressUnicodeString );
|
|
}
|
|
|
|
if( Error != ERROR_SUCCESS ) {
|
|
printf("Command failed, %ld.\n", Error );
|
|
return(1);
|
|
}
|
|
|
|
UNINIT_DEBUG_HEAP();
|
|
printf("Command successfully completed.\n");
|
|
|
|
|
|
return(0);
|
|
}
|
|
|