📄 optionmgr.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++
Module Name:
optionmgr.c
Abstract:
Options Manager for DhcpV6 client.
FrancisD
Environment:
User Level: Windows
Revision History:
--*/
#include "dhcpv6p.h"
//#include "precomp.h"
//#include "optionmgr.tmh"
DWORD
IniDhcpV6OptionMgrFindOption(
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule,
DHCPV6_OPTION_TYPE DhcpV6OptionType,
PDHCPV6_OPTION *ppDhcpV6Option
)
{
DWORD dwError = STATUS_NOT_FOUND;
PDHCPV6_OPTION pDhcpV6Option = pDhcpV6OptionModule->OptionsTable;
ULONG uIndex = 0;
for (uIndex = 0; uIndex < DHCPV6_MAX_OPTIONS; uIndex++, pDhcpV6Option++) {
if (pDhcpV6Option->DhcpV6OptionType == DhcpV6OptionType) {
dwError = ERROR_SUCCESS;
*ppDhcpV6Option = pDhcpV6Option;
break;
}
}
return dwError;
}
DWORD
IniDhcpV6OptionMgrSetOption(
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule,
DHCPV6_OPTION_TYPE DhcpV6OptionType,
BOOL bEnabled,
BOOL bRequired
)
{
DWORD dwError = 0;
PDHCPV6_OPTION pDhcpV6Option = NULL;
ULONG uLength = 0;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Set Option Type: %d, Enabled: %d", DhcpV6OptionType, bEnabled));
dwError = IniDhcpV6OptionMgrFindOption(
pDhcpV6OptionModule,
DhcpV6OptionType,
&pDhcpV6Option
);
BAIL_ON_WIN32_ERROR(dwError);
if (! bEnabled)
bRequired = FALSE;
pDhcpV6Option->bRequired = bRequired;
if (bEnabled == pDhcpV6Option->bEnabled) {
goto error;
}
pDhcpV6Option->bEnabled = bEnabled;
if (bEnabled) {
DHCPV6_INCREMENT(pDhcpV6OptionModule->uNumOfOptionsEnabled);
} else {
DHCPV6_DECREMENT(pDhcpV6OptionModule->uNumOfOptionsEnabled);
}
error:
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Set Option with Error: %!status!", dwError));
return dwError;
}
DWORD
IniDhcpV6OptionMgrLoadOptions(
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule
)
{
DWORD dwError = 0;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Load Option"));
// NOTE: Read from registry later when there may be more types
// For now hardcode
#ifdef UNDER_CE
dwError = IniDhcpV6OptionMgrSetOption(pDhcpV6OptionModule,
DHCPV6_OPTION_TYPE_DNS_SERVERS, TRUE, TRUE);
dwError = IniDhcpV6OptionMgrSetOption(pDhcpV6OptionModule,
DHCPV6_OPTION_TYPE_DOMAIN_LIST, TRUE, FALSE);
if (gbDHCPV6PDEnabled) {
dwError = IniDhcpV6OptionMgrSetOption(pDhcpV6OptionModule,
DHCPV6_OPTION_TYPE_IA_PD, TRUE, FALSE);
dwError = IniDhcpV6OptionMgrSetOption(pDhcpV6OptionModule,
DHCPV6_OPTION_TYPE_CLIENTID, TRUE, FALSE);
dwError = IniDhcpV6OptionMgrSetOption(pDhcpV6OptionModule,
DHCPV6_OPTION_TYPE_SERVERID, TRUE, FALSE);
}
#else
dwError = IniDhcpV6OptionMgrSetOption(pDhcpV6OptionModule, DHCPV6_OPTION_TYPE_DNS, TRUE);
#endif
BAIL_ON_WIN32_ERROR(dwError);
error:
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Load Option with Error: %!status!", dwError));
return dwError;
}
DWORD
InitDhcpV6OptionMgr(
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule, BOOL UsePD
)
{
DWORD dwError = 0;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Initializing Option Module"));
memset(pDhcpV6OptionModule, 0, sizeof(DHCPV6_OPTION_MODULE));
// Initialize the Options Table
#ifdef UNDER_CE
// note: OptionsTable[i].bEnabled & .bRequired are already memset to FALSE
pDhcpV6OptionModule->OptionsTable[0].DhcpV6OptionType = DHCPV6_OPTION_TYPE_DNS_SERVERS;
pDhcpV6OptionModule->OptionsTable[0].pDhcpV6OptionProcessRecv = DhcpV6OptionMgrProcessRecvDNS;
pDhcpV6OptionModule->OptionsTable[1].DhcpV6OptionType = DHCPV6_OPTION_TYPE_DOMAIN_LIST;
pDhcpV6OptionModule->OptionsTable[1].pDhcpV6OptionProcessRecv = DhcpV6OptionMgrProcessRecvDomainList;
if (UsePD) {
pDhcpV6OptionModule->OptionsTable[2].DhcpV6OptionType =
DHCPV6_OPTION_TYPE_IA_PD;
pDhcpV6OptionModule->OptionsTable[2].pDhcpV6OptionProcessRecv =
DhcpV6OptionMgrProcessRecvPD;
}
pDhcpV6OptionModule->OptionsTable[3].DhcpV6OptionType = DHCPV6_OPTION_TYPE_CLIENTID;
pDhcpV6OptionModule->OptionsTable[3].pDhcpV6OptionProcessRecv = DhcpV6OptionMgrProcessRecvClientID;
pDhcpV6OptionModule->OptionsTable[4].DhcpV6OptionType = DHCPV6_OPTION_TYPE_SERVERID;
pDhcpV6OptionModule->OptionsTable[4].pDhcpV6OptionProcessRecv = DhcpV6OptionMgrProcessRecvServerID;
#else
pDhcpV6OptionModule->uNumOfOptionsEnabled = 0;
pDhcpV6OptionModule->OptionsTable[0].DhcpV6OptionType = DHCPV6_OPTION_TYPE_DNS;
pDhcpV6OptionModule->OptionsTable[0].bEnabled = FALSE;
pDhcpV6OptionModule->OptionsTable[0].pDhcpV6OptionProcessRecv = DhcpV6OptionMgrProcessRecvDNS;
#endif
dwError = IniDhcpV6OptionMgrLoadOptions(pDhcpV6OptionModule);
BAIL_ON_WIN32_ERROR(dwError);
error:
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Initializing Option Module with Error: %!status!", dwError));
return dwError;
}
DWORD
DeInitDhcpV6OptionMgr(
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule
)
{
DWORD dwError = 0;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin DeInitializing Option Module"));
memset(pDhcpV6OptionModule, 0, sizeof(DHCPV6_OPTION_MODULE));
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End DeInitializing Option Module"));
return dwError;
}
DWORD
DhcpV6OptionMgrCreateOptionRequestPD(
PDHCPV6_ADAPT pDhcpV6Adapt,
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule,
PUCHAR pucOptionMessageBuffer,
USHORT usOptionLength
)
{
DWORD dwError = 0;
USHORT cLen;
USHORT *psCurLoc = (USHORT *)pucOptionMessageBuffer;
DHCPV6_IA_PD_OPTION PacketPD;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Create Option Request"));
// note: handle increments separately from the adds, I think some of the
// compilers didn't handle it correctly
// let's do ClientID first
cLen = (USHORT)pDhcpV6Adapt->cPhysicalAddr;
ASSERT(0 == (cLen & 1));
cLen &= 0xfffe;
cLen += 4; // add 2 for DUID-type + 2 for hardware type
*psCurLoc = htons(DHCPV6_OPTION_TYPE_CLIENTID);
psCurLoc++;
*psCurLoc = htons(cLen);
psCurLoc++;
*psCurLoc = htons(3); // DUID-type LL link-layer address
psCurLoc++;
*psCurLoc = htons(1); // hardware type
psCurLoc++;
memcpy(psCurLoc, pDhcpV6Adapt->PhysicalAddr, pDhcpV6Adapt->cPhysicalAddr);
psCurLoc += pDhcpV6Adapt->cPhysicalAddr >> 1;
if (pDhcpV6Adapt->pServerID &&
( (dhcpv6_state_srequest == pDhcpV6Adapt->DhcpV6State) ||
(dhcpv6_state_T1 == pDhcpV6Adapt->DhcpV6State))) {
// do the ServerID
cLen = pDhcpV6Adapt->cServerID;
ASSERT(0 == (cLen & 1));
*psCurLoc = htons(DHCPV6_OPTION_TYPE_SERVERID);
psCurLoc++;
*psCurLoc = htons(cLen);
psCurLoc++;
memcpy(psCurLoc, pDhcpV6Adapt->pServerID, cLen);
psCurLoc += cLen >> 1;
}
// handle ORO option
//ASSERT(usOptionLength == 4);
*psCurLoc = htons(DHCPV6_OPTION_TYPE_ORO);
psCurLoc++;
*psCurLoc = htons(4);
psCurLoc++;
*psCurLoc = htons(DHCPV6_OPTION_TYPE_DNS_SERVERS);
psCurLoc++;
*psCurLoc = htons(DHCPV6_OPTION_TYPE_IA_PD);
psCurLoc++;
// handle elapsed time option
*psCurLoc = htons(DHCPV6_OPTION_TYPE_ELAPSED_TIME);
psCurLoc++;
*psCurLoc = htons(2);
psCurLoc++;
*psCurLoc = 0;
psCurLoc++;
// handle the IA_PD option
*psCurLoc = htons(DHCPV6_OPTION_TYPE_IA_PD);
psCurLoc++;
if ((dhcpv6_state_srequest == pDhcpV6Adapt->DhcpV6State) ||
(dhcpv6_state_T1 == pDhcpV6Adapt->DhcpV6State) ||
(dhcpv6_state_T2 == pDhcpV6Adapt->DhcpV6State) ||
(dhcpv6_state_rebindconfirm== pDhcpV6Adapt->DhcpV6State)){
DHCPV6_IA_PREFIX_OPTION PacketPrefix;
DHCPV6_IA_PREFIX *pPrefix;
*psCurLoc = htons((IA_PD_OPTION_LEN + IA_PREFIX_OPTION_LEN + 4));
psCurLoc++;
// perhaps we should just store it in network order!
PacketPD.IAID = ntohl(pDhcpV6Adapt->pPdOption->IAID);
PacketPD.T1 = ntohl(pDhcpV6Adapt->pPdOption->T1);
PacketPD.T2 = ntohl(pDhcpV6Adapt->pPdOption->T2);
memcpy(psCurLoc, &(PacketPD.IAID), IA_PD_OPTION_LEN);
psCurLoc += 6;
// now do prefix stuff
pPrefix = &pDhcpV6Adapt->pPdOption->IAPrefix;
PacketPrefix.OptionCode = htons(DHCPV6_OPTION_TYPE_IA_PREFIX);
PacketPrefix.OptionLen = htons(IA_PREFIX_OPTION_LEN);
PacketPrefix.PreferredLifetime = htonl(pPrefix->PreferedLifetime);
PacketPrefix.ValidLifetime = htonl(pPrefix->ValidLifetime);
PacketPrefix.PrefixLength = pPrefix->cPrefix;
memcpy(&(PacketPrefix.IPv6Prefix), &pPrefix->PrefixAddr,
sizeof(IN6_ADDR));
// this time we're copying the header too so add 4
memcpy(psCurLoc, &PacketPrefix, IA_PREFIX_OPTION_LEN + 4);
// should we update psCurLoc's location?
} else {
*psCurLoc = htons(IA_PD_OPTION_LEN);
psCurLoc++;
}
//error:
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Creating Option Request with Error: %!status!", dwError));
return dwError;
}
DWORD
DhcpV6OptionMgrCreateOptionRequest(
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule,
PUCHAR pucOptionMessageBuffer,
USHORT usOptionLength
)
{
DWORD dwError = 0;
PDHCPV6_OPTION pDhcpV6OptionsTable = pDhcpV6OptionModule->OptionsTable;
PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader = (PDHCPV6_OPTION_HEADER)pucOptionMessageBuffer;
PUSHORT pusHeaderOptions = 0;
ULONG uIndex = 0;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Create Option Request"));
if (usOptionLength != sizeof(DHCPV6_OPTION_HEADER) + (2 * sizeof(USHORT))) {
dwError = ERROR_INVALID_PARAMETER;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_ERROR, ("ERROR Invalid Option Buffer Length"));
BAIL_ON_WIN32_ERROR(dwError);
}
pDhcpV6OptionHeader->OptionCode = htons(DHCPV6_OPTION_TYPE_ORO);
usOptionLength -= sizeof(DHCPV6_OPTION_HEADER);
pDhcpV6OptionHeader->OptionLength = htons(usOptionLength);
pusHeaderOptions = (PUSHORT)(&pDhcpV6OptionHeader[1]);
while(usOptionLength > 0 && uIndex < DHCPV6_MAX_OPTIONS) {
if (pDhcpV6OptionsTable[uIndex].bEnabled) {
*pusHeaderOptions = htons(pDhcpV6OptionsTable[uIndex].DhcpV6OptionType);
pusHeaderOptions++;
}
uIndex++;
usOptionLength -= sizeof(USHORT);
}
error:
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Creating Option Request with Error: %!status!", dwError));
return dwError;
}
DWORD
IniDhcpV6OptionMgrVerifyReply(
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule,
PUCHAR pucMessageBuffer,
ULONG uMessageBufferLength
)
{
DWORD dwError = 0;
ULONG uIndex = 0;
PDHCPV6_OPTION pDhcpV6OptionsTable = pDhcpV6OptionModule->OptionsTable;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Verifying Reply"));
for (uIndex = 0; uIndex < DHCPV6_MAX_OPTIONS; uIndex++) {
ULONG uOptionBufferLength = 0;
PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader = NULL;
USHORT usOptionLength = 0;
BOOL bFound = FALSE;
PUCHAR pucOptionMessage = NULL;
if (pDhcpV6OptionsTable[uIndex].bEnabled == FALSE) {
continue;
}
if (pDhcpV6OptionsTable[uIndex].bRequired == FALSE) {
continue;
}
uOptionBufferLength = uMessageBufferLength;
pucOptionMessage = pucMessageBuffer;
while(uOptionBufferLength > 0) {
DHCPV6_OPTION_TYPE DhcpV6OptionType = 0;
if (uOptionBufferLength < sizeof(DHCPV6_OPTION_HEADER)) {
dwError = ERROR_INVALID_PARAMETER;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, ("WARNING: Buffer Length Invalid - Packet should be discarded"));
BAIL_ON_WIN32_ERROR(dwError);
}
pDhcpV6OptionHeader = (PDHCPV6_OPTION_HEADER)pucOptionMessage;
uOptionBufferLength -= sizeof(DHCPV6_OPTION_HEADER);
pucOptionMessage += sizeof(DHCPV6_OPTION_HEADER);
usOptionLength = ntohs(pDhcpV6OptionHeader->OptionLength);
if (uOptionBufferLength < usOptionLength) {
dwError = ERROR_INVALID_PARAMETER;
DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, ("WARNING: Option Length Invalid - Packet should be discarded"));
BAIL_ON_WIN32_ERROR(dwError);
}
uOptionBufferLength -= usOptionLength;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -