📄 optionmgr.c
字号:
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 + -