471 lines
13 KiB
C
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
|