⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optionmgr.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -