?? dhcp.c
字號:
default:
fDone = FALSE;
break;
}
} else {
// we're in T2 stage don't use old addr.
pDhcp->IPAddr = 0;
}
}
} else { // else if (!fDiscover)
DEBUGMSG(ZONE_WARN, (TEXT("\tGetParams: failed badly!\n")));
// shall we try again?
pDhcp->IPAddr = 0;
}
} else { // if (SetDHCPNTE)
DEBUGMSG(ZONE_WARN,
(TEXT("DHCP: GetParams: adapter disappeared\r\n")));
Status = DHCP_NOCARD;
}
if (! fDone && ((pDhcp->SFlags & DHCPSTATE_DIALOGUE_BOX) == 0) &&
DHCP_NOCARD != Status &&
(cRetry == pDhcp->cRetryDialogue || cRetry == pDhcp->cMaxRetry)) {
pDhcp->SFlags |= DHCPSTATE_DIALOGUE_BOX;
CallNetMsgBox(NULL, NMB_FL_EXCLAIM | NMB_FL_OK |
NMB_FL_TOPMOST, NETUI_GETNETSTR_NO_IPADDR);
}
} // for(...)
if (fDone) {
pDhcp->SFlags &= ~DHCPSTATE_DIALOGUE_BOX;
}
} // if (pDhcp->Flags & DHCP_ENABLED_FL)
DEBUGMSG(ZONE_INIT, (TEXT("-GetParams: pDhcp 0x%X Ret: %d\n"), pDhcp, Status));
return Status;
} // GetParams()
STATUS DelDHCPInterface(PTSTR pAdapter, void *Nte, unsigned Context) {
STATUS Status;
DhcpInfo **ppDhcp, *pDhcp;
ppDhcp = _FindDhcp(NULL, pAdapter);
if (pDhcp = *ppDhcp) {
*ppDhcp = pDhcp->pNext;
CTEFreeLock(&v_GlobalListLock, 0);
TakeNetDown(pDhcp, FALSE, TRUE);
// we probably don't need to clear, but since we now have a flag
// to not clear if we don't have it set it should be safer
ClearDHCPNTE(pDhcp);
CloseDhcpSocket(pDhcp);
CTEFreeLock(&pDhcp->Lock, 0);
FreeDhcpInfo(pDhcp);
} else {
// let's check the worker Q
ppDhcp = &v_pWaitingList;
while (pDhcp = *ppDhcp) {
if (0 == _tcscmp(pDhcp->Name, pAdapter)) {
*ppDhcp = pDhcp->pNext;
FreeDhcpInfo(pDhcp);
break;
}
ppDhcp = &(pDhcp->pNext);
}
if (pDhcp) {
Status = DHCP_SUCCESS;
} else if (v_pCurrent &&
(0 == _tcscmp(v_pCurrent->Name, pAdapter))) {
ASSERT(NULL == v_pDelete);
v_pDelete = v_pCurrent;
Status = DHCP_SUCCESS;
} else {
DEBUGMSG(ZONE_ERROR,
(TEXT("DHCP: DelDHCPInterface: couldn't find Interface %s\r\n"),
pAdapter));
Status = DHCP_NOINTERFACE;
}
CTEFreeLock(&v_GlobalListLock, 0);
}
return Status;
} // DelDHCPInterface()
STATUS RenewDHCPAddr(PTSTR pAdapter, void *Nte, unsigned Context, char *pAddr,
unsigned cAddr) {
STATUS Status = DHCP_SUCCESS;
DhcpInfo **ppDhcp, *pDhcp;
int fNewSock = 0;
DhcpPkt Pkt;
int cPkt;
FILETIME CurTime;
int fStatus, fLockFreed = 0;
ppDhcp = _FindDhcp(NULL, pAdapter);
if (pDhcp = *ppDhcp) {
CTEFreeLock(&v_GlobalListLock, 0);
ASSERT(pDhcp->Nte == Nte);
ASSERT(pDhcp->NteContext == Context);
if (pDhcp->SFlags & DHCPSTATE_LEASE_EXPIRE) {
ASSERT(0);
// if this is the case, we shouldn't be on the established list!
Status = DHCP_FAILURE;
} else if (pDhcp->SFlags & DHCPSTATE_AUTO_CFG_IP) {
fLockFreed = TRUE;
TakeNetDown(pDhcp, FALSE, TRUE);
CTEFreeLock(&pDhcp->Lock, 0);
Status = RequestDHCPAddr(pAdapter, Nte, Context, pAddr, cAddr);
} else {
if (! pDhcp->Socket) {
fNewSock++;
Status = DhcpInitSock(pDhcp, pDhcp->IPAddr);
}
if (DHCP_SUCCESS == Status) {
BuildDhcpPkt(pDhcp, &Pkt, DHCPREQUEST, (NEW_PKT_FL), pDhcp->ReqOptions, &cPkt);
fStatus = TRUE; // SetDHCPNTE(pDhcp);
GetCurrentFT(&CurTime);
if (fStatus)
Status = SendDhcpPkt(pDhcp, &Pkt, cPkt, DHCPACK, 3);
else
Status = DHCP_NOCARD;
if (Status == DHCP_SUCCESS) {
CTEStopFTimer(&pDhcp->Timer);
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")));
CTEStopFTimer(&pDhcp->Timer);
TakeNetDown(pDhcp, TRUE, TRUE);
ClearDHCPNTE(pDhcp);
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);
// Status should be DHCP_NACK
goto Exit;
} // Status == DHCP_NACK
if (fNewSock)
CloseDhcpSocket(pDhcp);
} // DHCP_SUCCESS == Status
} // else DHCPSTATE_LEASE_EXPIRE
if (! fLockFreed)
CTEFreeLock(&pDhcp->Lock, 0);
} else { // if (_FindDhcp(...
// let's check the worker Q
pDhcp = v_pWaitingList;
while (pDhcp) {
if (0 == _tcscmp(pDhcp->Name, pAdapter)) {
break;
}
pDhcp = pDhcp->pNext;
}
if (! pDhcp) {
if (v_pCurrent && (0 == _tcscmp(v_pCurrent->Name, pAdapter)))
pDhcp = v_pCurrent;
}
CTEFreeLock(&v_GlobalListLock, 0);
if (pDhcp) {
// this means he is either on the waiting list or our current one
// so there is nothing more to do; return success.
Status = DHCP_SUCCESS;
} else {
Status = RequestDHCPAddr(pAdapter, Nte, Context, pAddr, cAddr);
}
}
Exit:
return Status;
} // RenewDHCPAddr()
STATUS RequestDHCPAddr(PTSTR pAdapter, void *Nte, unsigned Context, char *pAddr,
unsigned cAddr) {
DhcpInfo **ppDhcp, *pDhcp;
int cLen;
STATUS Status = DHCP_SUCCESS;
DEBUGMSG(ZONE_WARN, (TEXT("+RequestDHCPAddr: %s Context %d\r\n"),
pAdapter, Context));
ppDhcp = _FindDhcp(NULL, pAdapter);
if (pDhcp = *ppDhcp) {
DEBUGMSG(ZONE_WARN,
(TEXT("!RequestDHCPAddr: found previous pDhcp %X w. IP %X\r\n"),
pDhcp, pDhcp->IPAddr));
// we already have an object for this adapter
// take out of established list
*ppDhcp = pDhcp->pNext;
pDhcp->Nte = Nte;
pDhcp->NteContext = Context;
if (pAddr)
memcpy(pDhcp->PhysAddr, pAddr, cAddr);
CTEFreeLock(&pDhcp->Lock, 0);
} else {
cLen = (_tcslen(pAdapter) + 1) << 1;
if (pDhcp = NewDhcpInfo(cLen)) {
_tcscpy(pDhcp->Name, pAdapter);
pDhcp->Nte = Nte;
pDhcp->NteContext = Context;
if (pAddr)
memcpy(pDhcp->PhysAddr, pAddr, cAddr);
}
}
if (pDhcp) {
PutInWorkerQ(pDhcp);
} else
Status = DHCP_NOMEM;
CTEFreeLock(&v_GlobalListLock, 0);
ASSERT(v_GlobalListLock.OwnerThread != (HANDLE)GetCurrentThreadId());
DEBUGMSG(ZONE_WARN, (TEXT("-RequestDHCPAddr: Context %d\r\n"),
Context));
return Status;
} // RequestDHCPAddr()
STATUS ReleaseDHCPAddr(PTSTR pAdapter) {
DhcpInfo **ppDhcp, *pDhcp;
int cPkt;
STATUS Status;
DhcpPkt Pkt;
DEBUGMSG(ZONE_WARN, (TEXT("+ReleaseDHCPAddr: %s \n"), pAdapter));
// Find the object to release
Status = DHCP_NOINTERFACE;
ppDhcp = _FindDhcp(NULL, pAdapter);
if (pDhcp = *ppDhcp) {
// Don't want T1 or T2 timer to fire while we are in the middle
// of releasing...
// CTEStopFTimer(&pDhcp->Timer);
// this won't happen...ie: if it fires, it won't find us on the list
// Open the socket
if (DHCP_SUCCESS == (Status = DhcpInitSock(pDhcp, pDhcp->IPAddr))) {
// Build and transmit the Dhcp Release packet
BuildDhcpPkt(pDhcp, &Pkt, DHCPRELEASE, NEW_PKT_FL, NULL, &cPkt);
//
// Note that there is no ACK packet for a DHCPRELEASE, so there is
// no way to know for certain if a release is successful.
//
Status = DhcpSendDown(pDhcp, &Pkt, cPkt, pDhcp->DhcpServer);
// Inform TCP/IP that the IP address is no longer valid,
// Remove pDhcp from the global list
*ppDhcp = pDhcp->pNext;
CTEFreeLock(&v_GlobalListLock, 0);
TakeNetDown(pDhcp, TRUE, TRUE);
// we didn't set it, but in case someone else had...
ClearDHCPNTE(pDhcp);
CloseDhcpSocket(pDhcp);
CTEFreeLock(&pDhcp->Lock, 0);
FreeDhcpInfo(pDhcp);
} else {
CTEFreeLock(&v_GlobalListLock, 0);
CTEFreeLock(&pDhcp->Lock, 0);
}
} else {
CTEFreeLock(&v_GlobalListLock, 0);
}
return Status;
} // ReleaseDHCPAddr()
void DhcpWorkerThread() {
DhcpInfo *pInfo;
STATUS Status;
DWORD Size;
CTEGetLock(&v_GlobalListLock, 0);
while (pInfo = v_pWaitingList) {
// take him off the list
v_pWaitingList = pInfo->pNext;
v_pCurrent = pInfo;
pInfo->pNext = NULL;
CTEFreeLock(&v_GlobalListLock, 0);
// now try to get an address for him
if (DHCP_SUCCESS == (Status = DhcpInitSock(pInfo, 0))) {
CTEGetLock(&pInfo->Lock, 0);
if (! pInfo->Nte) {
Size = ETH_ADDR_LEN;
(*pfnSetDHCPNTE)(pInfo->NteContext, &pInfo->Nte, pInfo->PhysAddr, &Size);
}
Status = GetParams(pInfo);
CloseDhcpSocket(pInfo);
CTEFreeLock(&pInfo->Lock, 0);
CTEGetLock(&v_GlobalListLock, 0);
if (v_pDelete == v_pCurrent) {
if (DHCP_SUCCESS == Status) {
TakeNetDown(pInfo, FALSE, TRUE);
// we really shouldn't need to clear him, but to be safer
ClearDHCPNTE(pInfo);
Status = DHCP_FAILURE;
}
v_pDelete = NULL;
}
ASSERT(NULL == v_pDelete);
v_pCurrent = NULL;
if (DHCP_SUCCESS == Status) {
DEBUGMSG(ZONE_INIT,
(TEXT("Put Adapter in Established list\r\n")));
// cool put him on the established list
pInfo->pNext = v_pEstablishedList;
v_pEstablishedList = pInfo;
} else {
DEBUGMSG(ZONE_WARN,
(TEXT("\tDhcpWorkerThread: couldn't get Addr for pInfo 0x%X, Context 0x%X\r\n"),
pInfo, pInfo->NteContext));
FreeDhcpInfo(pInfo);
}
} else {
CTEGetLock(&v_GlobalListLock, 0);
if (v_pDelete == v_pCurrent) {
v_pDelete = NULL;
}
ASSERT(NULL == v_pDelete);
v_pCurrent = NULL;
// releaes global list lock since callnetmsgbox blocks our thread
CTEFreeLock(&v_GlobalListLock, 0);
FreeDhcpInfo(pInfo);
CallNetMsgBox(NULL, NMB_FL_EXCLAIM | NMB_FL_OK | NMB_FL_TOPMOST,
NETUI_GETNETSTR_NO_IPADDR);
CTEGetLock(&v_GlobalListLock, 0);
}
// we should have the Global Lock before going back up
DEBUGMSG(ZONE_WARN,
(TEXT("\tDhcpWorkerThread: loop 1: WaitList is 0x%X\r\n"),
v_pWaitingList));
}
v_pCurrent = NULL;
v_fWorkerThread = FALSE;
DEBUGMSG(ZONE_WARN,
(TEXT("-DhcpWorkerThread: WaitList is 0x%X\r\n"),
v_pWaitingList));
ASSERT(v_GlobalListLock.OwnerThread == (HANDLE)GetCurrentThreadId());
CTEFreeLock(&v_GlobalListLock, 0);
ASSERT(v_GlobalListLock.OwnerThread != (HANDLE)GetCurrentThreadId());
} // DhcpWorkerThread()
STATUS DhcpNotify(uint Code, PTSTR pAdapter, void *Nte, unsigned Context,
char *pAddr, unsigned cAddr) {
STATUS Status;
switch(Code) {
case DHCP_NOTIFY_DEL_INTERFACE:
Status = DelDHCPInterface(pAdapter, Nte, Context);
break;
case DHCP_REQUEST_ADDRESS:
Status = RequestDHCPAddr(pAdapter, Nte, Context, pAddr, cAddr);
break;
case DHCP_REQUEST_RELEASE:
Status = ReleaseDHCPAddr(pAdapter);
break;
case DHCP_REQUEST_RENEW:
Status = RenewDHCPAddr(pAdapter, Nte, Context, pAddr, cAddr);
break;
// the following are unhandled cases no one should be calling them
case DHCP_NOTIFY_ADD_INTERFACE:
default:
ASSERT(0);
Status = DHCP_FAILURE;
break;
}
ASSERT(v_GlobalListLock.OwnerThread != (HANDLE)GetCurrentThreadId());
return Status;
} // DhcpNotify()
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -