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

📄 optionmgr.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
            pucOptionMessage += usOptionLength;

            DhcpV6OptionType = ntohs(pDhcpV6OptionHeader->OptionCode);
            if (DhcpV6OptionType == pDhcpV6OptionsTable[uIndex].DhcpV6OptionType) {
                bFound = TRUE;
                break;
            }

            if (DHCPV6_OPTION_TYPE_STATUS_CODE == DhcpV6OptionType && 
                usOptionLength >= 2) {

                USHORT  *pHdr = (USHORT *)pDhcpV6OptionHeader;
                DHCPV6_STATUS_CODE  StatusCode; 
                
                // oh, oh we got some sort of status notification
                // check to see if they don't support prefix-del

                StatusCode = ntohs(pHdr[2]);
                
                if (DHCPV6_STATUS_NOPREFIXAVAIL == StatusCode) {
                    dwError = ERROR_INVALID_LEVEL;
                    goto error;
                }
            }
            
        }

        if (!bFound) {
            // Option not found
            dwError = ERROR_NOT_FOUND;
            DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, ("WARNING: Option Requirement: Type: %d Not met - Packet should be discarded", pDhcpV6OptionsTable[uIndex].DhcpV6OptionType));
            BAIL_ON_WIN32_ERROR(dwError);
        }
    }

error:

    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Verifying Reply with Error: %!status!", dwError));

    return dwError;
}


DWORD
DhcpV6OptionMgrProcessReply(
    PDHCPV6_ADAPT pDhcpV6Adapt,
    PDHCPV6_OPTION_MODULE pDhcpV6OptionModule,
    PUCHAR pucMessageBuffer,
    ULONG uMessageBufferLength
    )
{
    DWORD dwError = 0;
    PDHCPV6_OPTION pDhcpV6OptionsTable = pDhcpV6OptionModule->OptionsTable;
    ULONG uIndex = 0;
    PUCHAR pucOptionMessage = NULL;


    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Process Reply for Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));

    dwError = IniDhcpV6OptionMgrVerifyReply(
                    pDhcpV6OptionModule,
                    pucMessageBuffer,
                    uMessageBufferLength
                    );
    BAIL_ON_WIN32_ERROR(dwError);

    pucOptionMessage = pucMessageBuffer;
    while(uMessageBufferLength > 0) {
        DHCPV6_OPTION_TYPE DhcpV6OptionType = 0;
        USHORT usOptionLength = 0;
        PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader = NULL;

        if (uMessageBufferLength < 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;
        uMessageBufferLength -= sizeof(DHCPV6_OPTION_HEADER);
        pucOptionMessage += sizeof(DHCPV6_OPTION_HEADER);

        usOptionLength = ntohs(pDhcpV6OptionHeader->OptionLength);
        if (uMessageBufferLength < 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);
        }
        uMessageBufferLength -= usOptionLength;
        pucOptionMessage += usOptionLength;

        DhcpV6OptionType = ntohs(pDhcpV6OptionHeader->OptionCode);
        for (uIndex = 0; uIndex < DHCPV6_MAX_OPTIONS; uIndex++) {
            if (pDhcpV6OptionsTable[uIndex].DhcpV6OptionType != DhcpV6OptionType) {
                continue;
            }

            if (pDhcpV6OptionsTable[uIndex].bEnabled == FALSE) {
                break;
            }

            dwError = pDhcpV6OptionsTable[uIndex].pDhcpV6OptionProcessRecv(
                                                        pDhcpV6Adapt,
                                                        pDhcpV6OptionHeader
                                                        );
            BAIL_ON_WIN32_ERROR(dwError);

            break;
        }
    }

error:

    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Process Reply with Error: %!status!", dwError));

    return dwError;
}


DWORD
DhcpV6OptionMgrProcessRecvDNS(
    PDHCPV6_ADAPT pDhcpV6Adapt,
    PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader
    )
{
    DWORD dwError = 0;
    ULONG uNumOfDNSEntries = 0;
    PIN6_ADDR pIpv6DNSServers = NULL;
    ULONG uLength = 0;
    USHORT usOptionLength;


    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Process Received DNS for Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));

    usOptionLength = ntohs(pDhcpV6OptionHeader->OptionLength);

    if (usOptionLength % sizeof(IN6_ADDR) != 0) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, ("WARNING: Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    if (pDhcpV6Adapt->pIpv6DNSServers != NULL) {
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Releasing Previous %d DNS Entries Received", pDhcpV6Adapt->uNumOfDNSServers));

        pDhcpV6Adapt->uNumOfDNSServers = 0;
        FreeDHCPV6Mem(pDhcpV6Adapt->pIpv6DNSServers);
        pDhcpV6Adapt->pIpv6DNSServers = NULL;
    }

    uNumOfDNSEntries = usOptionLength / sizeof(IN6_ADDR);
    uLength = uNumOfDNSEntries * sizeof(IN6_ADDR);

    pIpv6DNSServers = AllocDHCPV6Mem(uLength);
    if (!pIpv6DNSServers) {
        dwError = ERROR_OUTOFMEMORY;
        BAIL_ON_WIN32_ERROR(dwError);
    }
    memset(pIpv6DNSServers, 0, uLength);

    memcpy(pIpv6DNSServers, &(pDhcpV6OptionHeader[1]), uLength);
    pDhcpV6Adapt->pIpv6DNSServers = pIpv6DNSServers;
    pDhcpV6Adapt->uNumOfDNSServers = uNumOfDNSEntries;

    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_INFO, ("DNS Entries Received: %d\n %!DHCPHEXDUMP!",
                    pDhcpV6Adapt->uNumOfDNSServers,
                    LOG_DHCPHEXDUMP(pDhcpV6Adapt->uNumOfDNSServers * sizeof(IN6_ADDR), (PUCHAR)pDhcpV6Adapt->pIpv6DNSServers)));

error:
    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Process Received DNS with Error: %!status!", dwError));

    return dwError;
}

DWORD
DhcpV6OptionMgrProcessRecvDomainList(
    PDHCPV6_ADAPT pDhcpV6Adapt,
    PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader
    )
{
    DWORD   dwError = 0;
    ULONG   uLength, uAddLen;
    USHORT  usOptionLength;
    PCHAR   p;


    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Process Received Domain List for Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));

    usOptionLength = ntohs(pDhcpV6OptionHeader->OptionLength);

    if (usOptionLength < 1) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, ("WARNING: Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    if (pDhcpV6Adapt->pDomainList) {
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, 
            ("Releasing Previous Domain list len %d", pDhcpV6Adapt->cDomainList));

        pDhcpV6Adapt->cDomainList = 0;
        FreeDHCPV6Mem(pDhcpV6Adapt->pDomainList);
        pDhcpV6Adapt->pDomainList = NULL;
    }

    uLength = usOptionLength;
    // always terminate domain list with '\0'
    p = (char *)&(pDhcpV6OptionHeader[1]);
    if (p[uLength - 1] != '\0')
        uAddLen = 1;
    else
        uAddLen = 0;

    pDhcpV6Adapt->pDomainList = AllocDHCPV6Mem(uLength + uAddLen);
    if (! pDhcpV6Adapt->pDomainList) {
        dwError = ERROR_OUTOFMEMORY;
        BAIL_ON_WIN32_ERROR(dwError);
    }

    memcpy(pDhcpV6Adapt->pDomainList, p, uLength);
    if (uAddLen)
        pDhcpV6Adapt->pDomainList[uLength] = '\0';

    pDhcpV6Adapt->cDomainList = uLength + uAddLen;

    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_INFO, ("Domain List Entries Received: %d\n %!DHCPHEXDUMP!",
            uLength,
            LOG_DHCPHEXDUMP(uLength, (PUCHAR)pDhcpV6Adapt->pDomainList)));

error:
    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Process Received DNS with Error: %!status!", dwError));

    return dwError;
}


DWORD
DhcpV6OptionMgrProcessRecvPD(
    PDHCPV6_ADAPT pDhcpV6Adapt,
    PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader
    )
{
    DWORD   dwError = 0;
    USHORT  cPrefixOption;
    USHORT  usOptionLength;
    DHCPV6_IA_PD_OPTION UNALIGNED       *pPacketPD;
    DHCPV6_IA_PREFIX_OPTION UNALIGNED   *pPacketPrefix;
    DWORD   T1, T2, PrefLife, ValidLife;


    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Process Received PD for Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));

    usOptionLength = ntohs(pDhcpV6OptionHeader->OptionLength);

    if (usOptionLength < 41) {  // 12 + 4 + 25
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, 
            ("WARNING: Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    pPacketPD = (DHCPV6_IA_PD_OPTION *)pDhcpV6OptionHeader;
    pPacketPrefix = pPacketPD->Prefix;
    if (DHCPV6_OPTION_TYPE_IA_PREFIX != ntohs(pPacketPrefix->OptionCode)) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, 
            ("WARNING: Prefix Option Code Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    cPrefixOption = ntohs(pPacketPrefix->OptionLen);

    if (cPrefixOption < 25) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, 
            ("WARNING: Prefix Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }
    
    if ((usOptionLength > 41) && (cPrefixOption > 25)) {
        if (pPacketPrefix->PrefixOptions[0]) {
            dwError = ERROR_INVALID_PARAMETER;
            DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, 
                ("WARNING: PD error code %d - Packet should be discarded", 
                pPacketPrefix->PrefixOptions[0]));
            BAIL_ON_WIN32_ERROR(dwError);
        }
    }

    T1 = ntohl(pPacketPD->T1);
    T2 = ntohl(pPacketPD->T2);
    if ((T1 && T2) && (T1 > T2)) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, 
            ("WARNING: Prefix Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    PrefLife = ntohl(pPacketPrefix->PreferredLifetime);
    ValidLife = ntohl(pPacketPrefix->ValidLifetime);
    if ((PrefLife > ValidLife) || (0 == ValidLife)) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, 
            ("WARNING: Prefix Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    if (! T1)
        T1 = PrefLife >> 1;
    if (! T2)
        T2 = PrefLife * 4 /5;
    if (T1 > T2)
        T1 = T2 >> 1;

    if (pDhcpV6Adapt->pPdOption) {
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, 
            ("Releasing Previous PD Option Received"));

        FreeDHCPV6Mem(pDhcpV6Adapt->pPdOption);
        pDhcpV6Adapt->pPdOption = NULL;
    }

    pDhcpV6Adapt->pPdOption = AllocDHCPV6Mem(sizeof(DHCPV6_PD_OPTION));
    if (!pDhcpV6Adapt->pPdOption) {
        dwError = ERROR_OUTOFMEMORY;
        BAIL_ON_WIN32_ERROR(dwError);
    }

    pDhcpV6Adapt->pPdOption->IAID = 0;
    ASSERT(0 == pPacketPD->IAID);

    pDhcpV6Adapt->pPdOption->T1 = T1;
    pDhcpV6Adapt->pPdOption->T2 = T2;

    pDhcpV6Adapt->pPdOption->IAPrefix.PreferedLifetime = PrefLife;
    pDhcpV6Adapt->pPdOption->IAPrefix.ValidLifetime = ValidLife;
    pDhcpV6Adapt->pPdOption->IAPrefix.cPrefix = pPacketPrefix->PrefixLength;

    memcpy(&(pDhcpV6Adapt->pPdOption->IAPrefix.PrefixAddr),
        pPacketPrefix->IPv6Prefix, sizeof(IN6_ADDR));

    GetCurrentFT (&(pDhcpV6Adapt->pPdOption->IAPrefix.IALeaseObtained));

    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_INFO, ("PD Entry recv'd: "));

error:
    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Process Received DNS with Error: %!status!", dwError));

    return dwError;
}


DWORD
DhcpV6OptionMgrProcessRecvClientID(
    PDHCPV6_ADAPT pDhcpV6Adapt,
    PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader
    )
{
    DWORD   dwError = 0;
    USHORT  usOptionLength;
    USHORT  *psCurLoc = (USHORT *)&(pDhcpV6OptionHeader[1]);

    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Process Received Domain List for Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));

    usOptionLength = ntohs(pDhcpV6OptionHeader->OptionLength);

    if (usOptionLength < (4 + pDhcpV6Adapt->cPhysicalAddr)) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, ("WARNING: Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    if (htons(3) != *psCurLoc)
        dwError = ERROR_INVALID_PARAMETER;
    psCurLoc++;
    if (htons(1) != *psCurLoc)
        dwError = ERROR_INVALID_PARAMETER;
    psCurLoc++;
    BAIL_ON_WIN32_ERROR(dwError);

    if (memcmp(psCurLoc, pDhcpV6Adapt->PhysicalAddr, pDhcpV6Adapt->cPhysicalAddr)) {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_WIN32_ERROR(dwError);
    }

error:
    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Process Received DNS with Error: %!status!", dwError));

    return dwError;
}


DWORD
DhcpV6OptionMgrProcessRecvServerID(
    PDHCPV6_ADAPT pDhcpV6Adapt,
    PDHCPV6_OPTION_HEADER pDhcpV6OptionHeader
    )
{
    DWORD   dwError = 0;
    USHORT  usOptionLength;

    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("Begin Process Received Domain List for Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));

    usOptionLength = ntohs(pDhcpV6OptionHeader->OptionLength);

    if (usOptionLength < 4 ) {
        dwError = ERROR_INVALID_PARAMETER;
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_WARN, ("WARNING: Option Length Invalid - Packet should be discarded"));
        BAIL_ON_WIN32_ERROR(dwError);
    }

    if (pDhcpV6Adapt->pServerID) {
        DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, 
            ("Releasing Previous PD Option Received"));

        FreeDHCPV6Mem(pDhcpV6Adapt->pServerID);
        pDhcpV6Adapt->pServerID = NULL;
        pDhcpV6Adapt->cServerID = 0;
    }

    pDhcpV6Adapt->pServerID = AllocDHCPV6Mem(usOptionLength);
    if (! pDhcpV6Adapt->pServerID) {
        dwError = ERROR_OUTOFMEMORY;
        BAIL_ON_WIN32_ERROR(dwError);
    }

    pDhcpV6Adapt->cServerID = usOptionLength;
    memcpy(pDhcpV6Adapt->pServerID, &(pDhcpV6OptionHeader[1]), usOptionLength);

error:
    DhcpV6Trace(DHCPV6_OPTION, DHCPV6_LOG_LEVEL_TRACE, ("End Process Received DNS with Error: %!status!", dwError));

    return dwError;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -