📄 dhcp.c
字号:
}
} else // if (Sock)
Status = GetLastError();
if (DHCP_SUCCESS == Status)
pInfo->Socket = Sock;
DEBUGMSG(ZONE_INIT, (TEXT("-DhcpInitSock: pInfo 0x%X/0x%X Ret: %d\r\n"),
pInfo, pInfo->Socket, Status));
return Status;
} // InitSocket()
//
// Function to call ARP's SetDHCPNTE - caller must have pDhcp->Lock
//
BOOL
SetDHCPNTE(
DhcpInfo * pDhcp
)
{
BOOL RetStatus = FALSE;
if (0 == (pDhcp->SFlags & DHCPSTATE_DHCPNTE_SET)) {
RetStatus = (*pfnSetDHCPNTE)(pDhcp->NteContext, NULL, NULL, NULL);
if (RetStatus)
pDhcp->SFlags |= DHCPSTATE_DHCPNTE_SET;
}
return RetStatus;
}
BOOL
ClearDHCPNTE(
DhcpInfo * pDhcp
)
{
BOOL RetStatus = FALSE;
if (pDhcp->SFlags & DHCPSTATE_DHCPNTE_SET) {
// even if this fails we're going to assume that we no longer have
// the dhcpnte set
pDhcp->SFlags &= ~DHCPSTATE_DHCPNTE_SET;
RetStatus = (*pfnSetDHCPNTE)(0x1fff, NULL, NULL, NULL);
}
return RetStatus;
}
void ProcessT2(DhcpInfo *pDhcp) {
STATUS Status = DHCP_SUCCESS;
DhcpPkt Pkt;
int cPkt;
FILETIME CurTime;
int fStatus;
DhcpInfo **ppDhcp;
DEBUGMSG(ZONE_TIMER, (TEXT("+ProcessT2: pDhcp 0x%X\r\n"), pDhcp));
if (*_FindDhcp(pDhcp, NULL)) {
CTEFreeLock(&v_GlobalListLock, 0);
pDhcp->SFlags |= DHCPSTATE_T2_EXPIRE;
if (DHCP_SUCCESS == (Status = DhcpInitSock(pDhcp, pDhcp->IPAddr))) {
BuildDhcpPkt(pDhcp, &Pkt, DHCPREQUEST, (NEW_PKT_FL), pDhcp->ReqOptions, &cPkt);
fStatus = SetDHCPNTE(pDhcp);
GetCurrentFT(&CurTime);
DEBUGMSG(ZONE_TIMER, (TEXT("\tProcess T2: CurTime: %x %x\r\n"),
CurTime.dwHighDateTime, CurTime.dwLowDateTime));
if (fStatus)
Status = SendDhcpPkt(pDhcp, &Pkt, cPkt, DHCPACK,
(ONCE_FL | BCAST_FL));
else
Status = DHCP_NOCARD;
if (Status == DHCP_SUCCESS) {
pDhcp->SFlags &= ~(DHCPSTATE_T2_EXPIRE | DHCPSTATE_T1_EXPIRE);
memcpy(&pDhcp->LeaseObtained, &CurTime, sizeof(CurTime));
SetDhcpConfig(pDhcp);
CalcT1Time(pDhcp);
} else if (Status == DHCP_NACK) {
DEBUGMSG(ZONE_WARN,
(TEXT("\t!ProcessT2: Take Net Down\r\n")));
TakeNetDown(pDhcp, TRUE, TRUE);
ClearDHCPNTE(pDhcp);
pDhcp->SFlags &= ~(DHCPSTATE_T2_EXPIRE | DHCPSTATE_T1_EXPIRE);
CloseDhcpSocket(pDhcp);
CTEFreeLock(&pDhcp->Lock, 0);
if (*(ppDhcp = _FindDhcp(pDhcp, NULL))) {
*ppDhcp = pDhcp->pNext;
// CallNetMsgBox(NULL, NMB_FL_EXCLAIM | NMB_FL_OK | NMB_FL_TOPMOST,
// NETUI_GETNETSTR_LEASE_EXPIRED);
PutInWorkerQ(pDhcp);
CTEFreeLock(&pDhcp->Lock, 0);
}
CTEFreeLock(&v_GlobalListLock, 0);
return;
} else {
CalcMidwayTime(pDhcp, pDhcp->Lease, (CTEEventRtn)ProcessT2,
(CTEEventRtn)ProcessExpire);
}
if (fStatus)
ClearDHCPNTE(pDhcp);
CloseDhcpSocket(pDhcp);
} else { // (DHCP_SUCCESS == DhcpInitSock())
DEBUGMSG(ZONE_WARN,
(TEXT("\t!ProcessT2: DhcpInitSock failed %d!!\r\n"),
Status));
CalcMidwayTime(pDhcp, pDhcp->Lease, (CTEEventRtn)ProcessT2,
(CTEEventRtn)ProcessExpire);
}
CTEFreeLock(&pDhcp->Lock, 0);
} else // if (*_FindDhcp())
CTEFreeLock(&v_GlobalListLock, 0);
DEBUGMSG(ZONE_TIMER, (TEXT("-ProcessT2: pDhcp 0x%X\r\n"),
pDhcp));
} // ProcessT2()
void ProcessT1(DhcpInfo *pDhcp) {
STATUS Status = DHCP_SUCCESS;
DhcpPkt Pkt;
int cPkt;
FILETIME CurTime;
int fStatus;
DhcpInfo **ppDhcp;
DEBUGMSG(ZONE_TIMER, (TEXT("+ProcessT1: pDhcp 0x%X\r\n"), pDhcp));
if (*_FindDhcp(pDhcp, NULL)) {
CTEFreeLock(&v_GlobalListLock, 0);
pDhcp->SFlags |= DHCPSTATE_T1_EXPIRE;
if (DHCP_SUCCESS == (Status = DhcpInitSock(pDhcp, pDhcp->IPAddr))) {
BuildDhcpPkt(pDhcp, &Pkt, DHCPREQUEST, (NEW_PKT_FL), pDhcp->ReqOptions, &cPkt);
fStatus = SetDHCPNTE(pDhcp);
GetCurrentFT(&CurTime);
DEBUGMSG(ZONE_TIMER, (TEXT("\tProcess T1: CurTime: %x %x\r\n"),
CurTime.dwHighDateTime, CurTime.dwLowDateTime));
if (fStatus)
Status = SendDhcpPkt(pDhcp, &Pkt, cPkt, DHCPACK, ONCE_FL);
else
Status = DHCP_NOCARD;
if (Status == DHCP_SUCCESS) {
pDhcp->SFlags &= ~(DHCPSTATE_T1_EXPIRE);
memcpy(&pDhcp->LeaseObtained, &CurTime, sizeof(CurTime));
SetDhcpConfig(pDhcp);
CalcT1Time(pDhcp);
} else if (Status == DHCP_NACK) {
// Take Net Down !!!
DEBUGMSG(ZONE_WARN,
(TEXT("\t!ProcessT1: Take Net Down\r\n")));
TakeNetDown(pDhcp, TRUE, TRUE);
ClearDHCPNTE(pDhcp);
pDhcp->SFlags &= ~(DHCPSTATE_T1_EXPIRE);
CloseDhcpSocket(pDhcp);
CTEFreeLock(&pDhcp->Lock, 0);
if (*(ppDhcp = _FindDhcp(pDhcp, NULL))) {
*ppDhcp = pDhcp->pNext;
// CallNetMsgBox(NULL, NMB_FL_EXCLAIM | NMB_FL_OK | NMB_FL_TOPMOST,
// NETUI_GETNETSTR_LEASE_EXPIRED);
PutInWorkerQ(pDhcp);
CTEFreeLock(&pDhcp->Lock, 0);
}
CTEFreeLock(&v_GlobalListLock, 0);
return;
} else {
CalcMidwayTime(pDhcp, pDhcp->T2, (CTEEventRtn)ProcessT1,
(CTEEventRtn)ProcessT2);
}
if (fStatus)
ClearDHCPNTE(pDhcp);
CloseDhcpSocket(pDhcp);
} else { // if (DHCP_SUCCESS == DhcpInitSock)
DEBUGMSG(ZONE_WARN,
(TEXT("\t!ProcessT1: DhcpInitSock failed %d!!\r\n"),
Status));
CalcMidwayTime(pDhcp, pDhcp->T2, (CTEEventRtn)ProcessT1,
(CTEEventRtn)ProcessT2);
}
CTEFreeLock(&pDhcp->Lock, 0);
} else // if (FindDhcp())
CTEFreeLock(&v_GlobalListLock, 0);
DEBUGMSG(ZONE_TIMER, (TEXT("-ProcessT1: pDhcp 0x%X\r\n"),
pDhcp));
} // ProcessT1()
#ifdef UNDER_CE
// Handles by which to notify applications of changes to IP data structures.
HANDLE g_hAddrChangeEvent;
void
NotifyXxxChange(HANDLE hEvent)
//
// Pulse the event to let applications know a change has occurred
//
{
if (hEvent)
{
PulseEvent(hEvent);
}
}
#endif //UNDER_CE
//
// PutNetUp - Cause TCP/IP to use DHCP negotiated IP address for this net.
// The TCP/IP stack will call our ARPResult function if there is an IP address conflict.
// ARPResult sets the ARPEvent to indicate it was called.
//
// Return: DHCP_* error code from comm\inc\dhcp.h
//
STATUS PutNetUp(DhcpInfo *pDhcp) {
int i, j;
pDhcp->ARPResult = ERROR_SUCCESS; // assume no IP address collision
ResetEvent(pDhcp->ARPEvent);
i = (*pfnIPSetNTEAddr)((ushort)pDhcp->NteContext, NULL,
pDhcp->IPAddr, pDhcp->SubnetMask, pDhcp->Gateway);
if (i == IP_PENDING)
WaitForSingleObject(pDhcp->ARPEvent, ARP_RESPONSE_WAIT);
else if (i != IP_SUCCESS) {
DEBUGMSG(ZONE_WARN, (L"DHCP:PutNetUp - IPSetNTEAddr failed!\n"));
return (i == IP_DUPLICATE_ADDRESS) ? DHCP_COLLISION : DHCP_FAILURE;
}
if (ERROR_SUCCESS == pDhcp->ARPResult) {
// no IP address collision, proceed
i = j = 0;
if (pDhcp->DNS[0]) {
i++;
if (pDhcp->DNS[1]) {
i++;
}
}
if (pDhcp->WinsServer[0]) {
j++;
if (pDhcp->WinsServer[1]) {
j++;
}
}
CallAfd(AddInterface)(pDhcp->Name, pDhcp->Nte, pDhcp->NteContext, 0, pDhcp->IPAddr,
pDhcp->SubnetMask, i, pDhcp->DNS, j, pDhcp->WinsServer);
NotifyXxxChange(g_hAddrChangeEvent);
return DHCP_SUCCESS;
} else {
DEBUGMSG(ZONE_WARN, (L"DHCP:PutNetUp - ARPResult == %d, assuming IP addr collision\n", pDhcp->ARPResult));
return DHCP_COLLISION;
}
} // PutNetUp()
STATUS DhcpSendDown(DhcpInfo *pDhcp, DhcpPkt *pPkt, int cPkt, int DestIP);
void DhcpDecline(DhcpInfo * pDhcp, DhcpPkt *pPkt) {
int cPkt;
BuildDhcpPkt(pDhcp, pPkt, DHCPDECLINE, RIP_PKT_FL|NEW_PKT_FL, NULL, &cPkt);
DhcpSendDown(pDhcp, pPkt, cPkt, INADDR_BROADCAST);
// AFD info not added at this point
TakeNetDown(pDhcp, TRUE, FALSE);
}
BOOL CanUseCachedLease(DhcpInfo * pDhcp) {
FILETIME BeginTime, EndTime;
// we only try to use our old lease if we're not in T2 stage!
EndTime.dwHighDateTime = 0;
EndTime.dwLowDateTime = pDhcp->T2;
mul64_32_64(&EndTime, TEN_M, &EndTime);
add64_64_64(&pDhcp->LeaseObtained, &EndTime, &EndTime);
GetCurrentFT(&BeginTime);
if (CompareFileTime(&EndTime, &BeginTime) >= 0) {
return TRUE;
}
return FALSE;
} // CanUseCachedLease
STATUS GetParams(DhcpInfo *pDhcp) {
STATUS Status = DHCP_SUCCESS;
DhcpPkt Pkt;
int cPkt, fDiscover, Flags, fDone;
FILETIME BeginTime;
uint cRetry, cDelay;
DEBUGMSG(ZONE_INIT, (TEXT("+GetParams: pDhcp 0x%X/0x%X\n"),
pDhcp, pDhcp->Socket));
cRetry = fDone = 0;
pDhcp->SFlags &= ~(DHCPSTATE_T1_EXPIRE | DHCPSTATE_T2_EXPIRE |
DHCPSTATE_LEASE_EXPIRE | DHCPSTATE_SAW_DHCP_SRV);
GetDhcpConfig(pDhcp);
if (pDhcp->Flags & DHCP_ENABLED_FL) {
// If the IP address is currently auto cfg and the user has requested "ipconfig /renew"
// then stop the 5 minute discover timer and force a discover to happen
if (pDhcp->SFlags & DHCPSTATE_AUTO_CFG_IP) {
CTEStopFTimer(&pDhcp->Timer);
pDhcp->SFlags &= ~DHCPSTATE_AUTO_CFG_IP;
pDhcp->IPAddr = 0; // force a discover
}
for ( ; ! fDone && cRetry <= pDhcp->cMaxRetry; cRetry++) {
cDelay = (GetTickCount() % pDhcp->InitDelay);
Sleep(cDelay);
if (SetDHCPNTE(pDhcp)) {
Status = DHCP_SUCCESS;
GetCurrentFT(&BeginTime);
fDiscover = (!pDhcp->IPAddr) || (pDhcp->Flags & OPTION_CHANGE_FL);
if (fDiscover) { // if no prev IP or lease exp. or option change
pDhcp->IPAddr = 0;
pDhcp->Flags &= ~OPTION_CHANGE_FL;
BuildDhcpPkt(pDhcp, &Pkt, DHCPDISCOVER, (NEW_PKT_FL), pDhcp->ReqOptions, &cPkt);
Status = SendDhcpPkt(pDhcp, &Pkt, cPkt, DHCPOFFER,
BCAST_FL | DFT_LOOP_FL);
}
if (DHCP_SUCCESS == Status) {
Flags = RIP_PKT_FL; // request IP addr must be filled in
if (fDiscover)
Flags |= SID_PKT_FL;
else {
Flags |= NEW_PKT_FL;
}
BuildDhcpPkt(pDhcp, &Pkt, DHCPREQUEST, Flags, pDhcp->ReqOptions, &cPkt);
Status = SendDhcpPkt(pDhcp, &Pkt, cPkt, DHCPACK,
BCAST_FL | DFT_LOOP_FL);
}
ClearDHCPNTE(pDhcp);
if ((pDhcp->Flags & AUTO_IP_ENABLED_FL) &&
(!(pDhcp->SFlags & DHCPSTATE_SAW_DHCP_SRV))) {
// No response from a DHCP server, so try AutoIP.
DEBUGMSG(ZONE_AUTOIP, (TEXT("DHCP:GetParams - No response from DHCP server, trying AutoIP\n")));
Status = AutoIP(pDhcp);
}
if (DHCP_SUCCESS == Status) {
memcpy(&pDhcp->LeaseObtained, &BeginTime, sizeof(BeginTime));
SetDhcpConfig(pDhcp);
fDone = TRUE;
// We need to PutNetUp() here only when we've negotiated a lease with a DHCP server.
// If we didn't auto configure and didn't see a DHCP server, then AutoIP() was able to
// ping the default gateway so it decided to use the cached lease already.
if ((!(pDhcp->SFlags & DHCPSTATE_AUTO_CFG_IP)) &&
(pDhcp->SFlags & DHCPSTATE_SAW_DHCP_SRV)) {
Status = PutNetUp(pDhcp);
switch (Status) {
case DHCP_SUCCESS:
CalcT1Time(pDhcp);
break;
case DHCP_COLLISION:
DhcpDecline(pDhcp, &Pkt);
// fall through
default:
fDone = FALSE;
break;
}
}
} else if (DHCP_NACK == Status) {
pDhcp->IPAddr = 0;
} else if (!fDiscover) {
// didn't get a NAK see if we can use our old lease
if (pDhcp->IPAddr) {
if (CanUseCachedLease(pDhcp)) {
DEBUGMSG(ZONE_WARN,
(TEXT("\tGetParams: using cached DHCP lease\r\n")));
CallNetMsgBox(NULL, NMB_FL_OK, NETUI_GETNETSTR_CACHED_LEASE);
Status = PutNetUp(pDhcp);
switch (Status) {
case DHCP_SUCCESS:
// even if we're already in T1 stage this should work
// it just sets up a timer to call ProcessT1 right away
// ProcessT1 should then do the right thing
CalcT1Time(pDhcp);
fDone = TRUE;
break;
case DHCP_COLLISION:
DhcpDecline(pDhcp, &Pkt);
// fall through
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -