windows-nt/Source/XPSP1/NT/net/dhcp/client/nt/mdhcptst.c
2020-09-26 16:20:57 +08:00

471 lines
13 KiB
C

/*++
Copyright (C) 1999 Microsoft Corporation
Module Name:
mdhcptst.c
--*/
#include "precomp.h"
// only when the api is defined!
#include <dhcploc.h>
#include <dhcppro.h>
#include <mdhcpcli.h>
#define CREATE_NEW_REQUEST_FROM_RESPONSE(pRequest, pResponse) { \
(pRequest)->LeaseStartTime = (pRequest)->MaxLeaseStartTime = 0; \
(pRequest)->LeaseDuration = (pRequest)->MinLeaseDuration = 0; \
(pRequest)->MinAddrCount = (pRequest)->AddrCount = (pResponse)->AddrCount; \
(pRequest)->ServerAddress = (pResponse)->ServerAddress; \
memcpy((pRequest)->pAddrBuf, (pResponse)->pAddrBuf, sizeof (DWORD)*(pRequest)->AddrCount); \
}
typedef enum _cmd{
EnumScope = 1,
RequestAddr = 2,
RenewAddr = 3,
ReleaseAddr = 4,
ExitLoop = 99
} COMMAND;
PMCAST_SCOPE_ENTRY gScopeList = NULL;
DWORD gScopeCount = 0;
LPMCAST_CLIENT_UID gAddrRequestId = NULL;
typedef struct _LeaseEntry {
IPNG_ADDRESS ScopeID;
PMCAST_LEASE_RESPONSE pLeaseInfo;
LPMCAST_CLIENT_UID pRequestID;
LIST_ENTRY Linkage;
} LEASE_ENTRY, *PLEASE_ENTRY;
LIST_ENTRY gLeaseList;
void
InitializeGlobalData()
{
InitializeListHead(&gLeaseList);
return;
}
void
DisplayMenu()
{
printf("MDHCP Test Menu\n");
printf("===============\n");
printf("[1] - Enumerate Scopes:\n");
printf("[2] - Request Address:\n");
printf("[3] - Renew Address:\n");
printf("[4] - Release Address: \n");
printf("[99] - Exit:\n");
}
int
GetCommand()
{
DWORD cmd;
printf("Enter choice:");
if(scanf("%d",&cmd)) return cmd;
return 0;
}
DWORD
EnumScopes()
{
DWORD Error;
DWORD BufLen;
if ( gScopeList ) {
DhcpFreeMemory( gScopeList );
gScopeList = NULL;
}
Error = McastEnumerateScopes(
AF_INET,
TRUE,
NULL,
&BufLen,
&gScopeCount
);
if (ERROR_SUCCESS != Error) {
printf("Could not get the scope buf length, %ld\n",Error );
return Error;
}
gScopeList = DhcpAllocateMemory( BufLen );
Error = McastEnumerateScopes(
AF_INET,
FALSE,
gScopeList,
&BufLen,
&gScopeCount);
if (ERROR_SUCCESS != Error) {
printf("Could not get the scope list- 2nd call, %ld\n",Error );
DhcpFreeMemory( gScopeList );
gScopeList = NULL;
return Error;
}
DhcpAssert( gScopeCount > 0 );
return Error;
}
void
DisplayScopes()
{
DWORD i;
PMCAST_SCOPE_ENTRY pScope = gScopeList;
for (i = 0;i<gScopeCount; i++,pScope++) {
printf("[%d] - ScopeId %lx, LastAddr %lx, ttl %d, Name %ws\n",
i+1,ntohl(pScope->ScopeCtx.ScopeID.IpAddrV4),
ntohl(pScope->LastAddr.IpAddrV4), pScope->TTL, pScope->ScopeDesc.Buffer);
}
return;
}
void
PrintLeaseInfo(PMCAST_LEASE_RESPONSE pLeaseInfo, BOOL Verbose )
{
DHCP_IP_ADDRESS IpAddress = *(DWORD UNALIGNED *)pLeaseInfo->pAddrBuf;
time_t tempTime;
printf("Obtained IPAddress - %s\n",inet_ntoa(*(struct in_addr *)&IpAddress));
if ( Verbose ) {
tempTime = pLeaseInfo->LeaseEndTime;
printf("Expires - %.19s", asctime(localtime(&tempTime)));
}
}
VOID
DisplayCurrentLeases()
{
PLEASE_ENTRY pLeaseEntry;
PLIST_ENTRY p;
DWORD i;
for (p = gLeaseList.Flink,i=1; p != &gLeaseList; p = p->Flink,i++ ) {
pLeaseEntry = CONTAINING_RECORD(p, LEASE_ENTRY, Linkage);
printf("[%d] ", i);PrintLeaseInfo( pLeaseEntry->pLeaseInfo, FALSE );
}
return;
}
PLEASE_ENTRY
SelectFromCurrentLease(COMMAND cmd)
{
PLIST_ENTRY p;
DWORD index;
DWORD i;
PLEASE_ENTRY pLeaseEntry = NULL;
if (cmd != RenewAddr && cmd != ReleaseAddr) {
DhcpAssert( FALSE );
}
printf("CURRENT LEASE ASSIGNMENTS\n");
printf("-------------------------\n");
DisplayCurrentLeases();
printf("Select the lease you want to %s\n", RenewAddr == cmd ? "Renew" : "Release" );
index = GetCommand();
if ( !index ) {
printf("Lease index invalid\n");
return NULL;
}
for (p = gLeaseList.Flink,i=0; p != &gLeaseList; p = p->Flink ) {
if (++i == index) {
pLeaseEntry = CONTAINING_RECORD(p, LEASE_ENTRY, Linkage);
return pLeaseEntry;
}
}
printf("Error:invalid selection, choose the index from the list of the leases above\n");
return NULL;
}
DWORD
ReleaseAddress()
{
PLEASE_ENTRY pLeaseEntry;
PMCAST_LEASE_REQUEST AddrRequest;
DWORD Error;
DWORD i;
pLeaseEntry = SelectFromCurrentLease(ReleaseAddr);
if (!pLeaseEntry) {
return ERROR_FILE_NOT_FOUND;
}
AddrRequest = DhcpAllocateMemory( sizeof( *AddrRequest ) + sizeof(DHCP_IP_ADDRESS));
if (!AddrRequest) {
printf("Failed to allocate lease info struct\n",AddrRequest);
return ERROR_NOT_ENOUGH_MEMORY;
}
RtlZeroMemory(AddrRequest, sizeof(*AddrRequest) + sizeof(DHCP_IP_ADDRESS));
AddrRequest->pAddrBuf = (PBYTE) AddrRequest + sizeof(*AddrRequest);
CREATE_NEW_REQUEST_FROM_RESPONSE(AddrRequest, pLeaseEntry->pLeaseInfo);
Error = McastReleaseAddress(
AF_INET,
pLeaseEntry->pRequestID,
AddrRequest
);
if (ERROR_SUCCESS == Error ) {
printf("Lease Released successfully\n");
RemoveEntryList( &pLeaseEntry->Linkage );
// free the old lease structure.
DhcpFreeMemory( pLeaseEntry->pRequestID );
DhcpFreeMemory( pLeaseEntry->pLeaseInfo );
}
DhcpFreeMemory(AddrRequest);
return Error;
}
DWORD
RenewAddress()
{
PLEASE_ENTRY pLeaseEntry;
PMCAST_LEASE_REQUEST AddrRequest;
PMCAST_LEASE_RESPONSE AddrResponse;
PMCAST_LEASE_RESPONSE pLeaseInfo;
PMCAST_SCOPE_ENTRY Scope;
DWORD Error;
DWORD i;
pLeaseEntry = SelectFromCurrentLease(RenewAddr);
if (!pLeaseEntry) {
return ERROR_FILE_NOT_FOUND;
}
pLeaseInfo = pLeaseEntry->pLeaseInfo;
// find the scope ctx for this scope id.
if (pLeaseEntry->ScopeID.IpAddrV4) {
for (i=0;i<gScopeCount;i++) {
if (pLeaseEntry->ScopeID.IpAddrV4 == gScopeList[i].ScopeCtx.ScopeID.IpAddrV4) {
Scope = &gScopeList[i];
break;
}
}
if (i >= gScopeCount) {
printf("Could not find the scope ctx for the scope id %ld of this address\n",pLeaseEntry->ScopeID.IpAddrV4);
return ERROR_FILE_NOT_FOUND;
}
} else {
// default scope
Scope = NULL;
}
AddrRequest = DhcpAllocateMemory( sizeof( *AddrRequest ) + sizeof(DHCP_IP_ADDRESS));
if (!AddrRequest) {
printf("Failed to allocate lease info struct\n",AddrRequest);
return ERROR_NOT_ENOUGH_MEMORY;
}
RtlZeroMemory(AddrRequest, sizeof(*AddrRequest) + sizeof(DHCP_IP_ADDRESS));
AddrRequest->pAddrBuf = (PBYTE) AddrRequest + sizeof(*AddrRequest);
CREATE_NEW_REQUEST_FROM_RESPONSE(AddrRequest, pLeaseInfo);
AddrResponse = DhcpAllocateMemory( sizeof( *AddrResponse ) + sizeof(DHCP_IP_ADDRESS));
if (!AddrResponse) {
printf("Failed to allocate lease info struct\n",AddrResponse);
return ERROR_NOT_ENOUGH_MEMORY;
}
RtlZeroMemory(AddrResponse, sizeof(*AddrResponse) + sizeof(DHCP_IP_ADDRESS));
AddrResponse->pAddrBuf = (PBYTE) AddrResponse + sizeof(*AddrResponse);
AddrResponse->AddrCount = 1;
Error = McastRenewAddress(
AF_INET,
pLeaseEntry->pRequestID,
AddrRequest,
AddrResponse
);
if (ERROR_SUCCESS == Error ) {
printf("Lease Renew'd successfully\n");
PrintLeaseInfo( AddrResponse, TRUE );
pLeaseEntry->pLeaseInfo = AddrResponse;
// free the old lease structure.
DhcpFreeMemory( pLeaseInfo );
} else {
DhcpFreeMemory( AddrResponse );
}
DhcpFreeMemory( AddrRequest );
return Error;
}
DWORD
RequestAddress()
{
PMCAST_LEASE_REQUEST AddrRequest;
PMCAST_LEASE_RESPONSE AddrResponse;
LPMCAST_CLIENT_UID pRequestID;
DWORD index;
DWORD Error;
PLEASE_ENTRY pLeaseEntry;
DisplayScopes();
printf("Select the scope entry(0 for default scope)\n");
index = GetCommand();
if ( index > gScopeCount ) {
printf("Scope index out of range\n");
return ERROR_INVALID_PARAMETER;
}
AddrResponse = DhcpAllocateMemory( sizeof( *AddrResponse ) + sizeof(DHCP_IP_ADDRESS));
if (!AddrResponse) {
printf("Failed to allocate lease info struct\n",AddrResponse);
return ERROR_NOT_ENOUGH_MEMORY;
}
RtlZeroMemory(AddrResponse, sizeof(*AddrResponse)+ sizeof(DHCP_IP_ADDRESS));
AddrResponse->pAddrBuf = (PBYTE) AddrResponse + sizeof(*AddrResponse);
AddrRequest = DhcpAllocateMemory( sizeof( *AddrRequest ));
if (!AddrRequest) {
printf("Failed to allocate lease info struct\n",AddrRequest);
return ERROR_NOT_ENOUGH_MEMORY;
}
RtlZeroMemory(AddrRequest, sizeof(*AddrRequest));
AddrRequest->AddrCount = AddrResponse->AddrCount = 1;
pRequestID = DhcpAllocateMemory(sizeof(*pRequestID) + MCAST_CLIENT_ID_LEN);
if (!pRequestID) {
return ERROR_NOT_ENOUGH_MEMORY;
}
pRequestID->ClientUID = (char *)pRequestID + sizeof(*pRequestID);
pRequestID->ClientUIDLength = MCAST_CLIENT_ID_LEN;
Error = McastGenUID( pRequestID );
DhcpAssert( ERROR_SUCCESS == Error );
Error = McastRequestAddress(
AF_INET,
pRequestID,
index ? &gScopeList[index-1].ScopeCtx : NULL,
AddrRequest,
AddrResponse
);
if (ERROR_SUCCESS == Error ) {
printf("Lease obtained successfully\n");
PrintLeaseInfo( AddrResponse, TRUE );
// now copy this lease into our global structure.
pLeaseEntry = DhcpAllocateMemory( sizeof(LEASE_ENTRY) );
if (!pLeaseEntry) {
printf("Failed to allocate lease entry item\n");
return ERROR_NOT_ENOUGH_MEMORY;
}
pLeaseEntry->pLeaseInfo = AddrResponse;
pLeaseEntry->ScopeID.IpAddrV4 = index ? gScopeList[index-1].ScopeCtx.ScopeID.IpAddrV4 : 0;
pLeaseEntry->pRequestID = pRequestID;
InsertTailList(&gLeaseList, &pLeaseEntry->Linkage);
} else {
DhcpFreeMemory( pRequestID );
DhcpFreeMemory( AddrResponse );
}
DhcpFreeMemory( AddrRequest );
return Error;
}
int
__cdecl
main( int argc, char *argv[])
{
DWORD cmd;
DWORD Error;
DWORD Version;
InitializeGlobalData();
Version = MCAST_API_CURRENT_VERSION;
if (ERROR_SUCCESS != McastApiStartup(&Version)) {
printf("Current version %d not supported, Api Impl version %d\n",
MCAST_API_CURRENT_VERSION, Version);
return 0;
}
DisplayMenu();
while(cmd = GetCommand() ){
switch (cmd) {
case EnumScope:
Error = EnumScopes();
if (ERROR_SUCCESS != Error ) {
printf("Enumerate Scope returned failures, %ld\n",Error);
} else {
DisplayScopes();
}
break;
case RequestAddr:
Error = RequestAddress();
if (ERROR_SUCCESS != Error ) {
printf("RequestAddress returned failures, %ld\n",Error);
}
break;
case RenewAddr:
Error = RenewAddress();
if (ERROR_SUCCESS != Error ) {
printf("RenewAddress returned failures, %ld\n",Error);
}
break;
case ReleaseAddr:
Error = ReleaseAddress();
if (ERROR_SUCCESS != Error ) {
printf("ReleaseAddress returned failures, %ld\n",Error);
}
break;
case ExitLoop:
printf("Exiting\n");
return 0;
default:
printf("invalid choice\n");
break;
}
DisplayMenu();
}
return 0;
}
#if DBG
VOID
DhcpPrintRoutine(
IN DWORD DebugFlag,
IN LPSTR Format,
...
)
{
#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