?? dhcp.c
字號:
HKEY
OpenDHCPKey(
DhcpInfo * pDhcp
)
{
TCHAR Buffer[MAX_REG_STR];
HKEY hKey;
LONG hRes;
_tcscpy (Buffer, COMM_REG_KEY);
_tcscat (Buffer, pDhcp->Name);
_tcscat (Buffer, TEXT("\\Parms\\TcpIp"));
hRes = RegOpenKeyEx (HKEY_LOCAL_MACHINE, Buffer, 0, 0, &hKey);
if (hRes) {
return NULL;
}
return hKey;
}
STATUS GetDhcpConfig(DhcpInfo *pDhcp) {
HKEY hKey;
BOOL fStatus;
uint fDhcpEnabled;
int i;
DEBUGMSG (ZONE_INIT, (TEXT("+GetDhcpConfig:\r\n")));
// Open the Registry Key.
hKey = OpenDHCPKey(pDhcp);
if (hKey) {
fStatus = GetRegDWORDValue(hKey, TEXT("EnableDHCP"),
&fDhcpEnabled);
if (fStatus && fDhcpEnabled)
pDhcp->Flags |= DHCP_ENABLED_FL;
fStatus = GetRegIPAddr(hKey, TEXT("DhcpIPAddress"), &pDhcp->IPAddr, 1);
if (fStatus && pDhcp->IPAddr) {
fStatus = GetRegIPAddr(hKey, TEXT("DhcpSubnetMask"), &pDhcp->SubnetMask, 1);
if (fStatus && pDhcp->SubnetMask) {
// Get the DhcpServer
GetRegIPAddr(hKey, TEXT("DhcpServer"), &pDhcp->DhcpServer, 1);
// Get the DhcpDftGateway
GetRegIPAddr(hKey, TEXT("DhcpDefaultGateway"), &pDhcp->Gateway, 1);
GetRegIPAddr(hKey, TEXT("DhcpDNS"), pDhcp->DNS, 2);
GetRegIPAddr(hKey, TEXT("DhcpWINS"), pDhcp->WinsServer, 2);
// Get Lease Info
GetRegDWORDValue(hKey, TEXT("LeaseObtainedLow"),
&pDhcp->LeaseObtained.dwLowDateTime);
GetRegDWORDValue(hKey, TEXT("LeaseObtainedHigh"),
&pDhcp->LeaseObtained.dwHighDateTime);
GetRegDWORDValue(hKey, TEXT("Lease"), &pDhcp->Lease);
// Get T1 & T2
GetRegDWORDValue(hKey, TEXT("T1"), &pDhcp->T1);
GetRegDWORDValue(hKey, TEXT("T2"), &pDhcp->T2);
}
}
pDhcp->cMaxRetry = DEFAULT_MAX_RETRIES;
pDhcp->InitDelay = DEFAULT_INIT_DELAY;
pDhcp->cRetryDialogue = DEFAULT_RETRY_DIALOGUE;
// Get MaxRetries, InitDelayInterval
GetRegDWORDValue(hKey, TEXT("DhcpMaxRetry"), &pDhcp->cMaxRetry);
GetRegDWORDValue(hKey, TEXT("DhcpInitDelayInterval"), &pDhcp->InitDelay);
GetRegDWORDValue(hKey, TEXT("DhcpRetryDialogue"), &pDhcp->cRetryDialogue);
i = 0;
GetRegDWORDValue(hKey, TEXT("DhcpNoMacCompare"), &i);
if (i)
pDhcp->Flags |= NO_MAC_COMPARE_FL;
else
pDhcp->Flags &= ~NO_MAC_COMPARE_FL;
GetReqOptions(hKey, pDhcp);
// Get auto IP config state
if (GetRegDWORDValue(hKey, TEXT("AutoCfg"), (LPDWORD)&i)) {
// auto IP config is enabled by default
if (!i) {
pDhcp->Flags &= ~AUTO_IP_ENABLED_FL; // user wants it disabled
}
}
if (pDhcp->Flags & AUTO_IP_ENABLED_FL) {
GetRegDWORDValue(hKey, TEXT("AutoSeed"), &pDhcp->AutoSeed);
GetRegIPAddr(hKey, TEXT("AutoIP"), &pDhcp->AutoIPAddr, 1);
GetRegIPAddr(hKey, TEXT("AutoSubnet"), &pDhcp->AutoSubnet, 1);
GetRegIPAddr(hKey, TEXT("AutoMask"), &pDhcp->AutoMask, 1);
GetRegDWORDValue(hKey, TEXT("AutoInterval"), &pDhcp->AutoInterval);
}
RegCloseKey(hKey);
} // if (hKey)
DEBUGMSG (ZONE_INIT, (TEXT("-GetDhcpConfig:\r\n")));
return DHCP_SUCCESS;
} // GetDhcpConfig()
STATUS SetDhcpConfig(DhcpInfo *pDhcp) {
TCHAR Buffer[MAX_REG_STR];
HKEY hKey;
LONG hRes;
BOOL fStatus;
int i;
DEBUGMSG (ZONE_INIT, (TEXT("+SetDhcpConfig:\r\n")));
// Open the Registry Key.
hKey = OpenDHCPKey(pDhcp);
if (hKey) {
SetRegDWORDValue(hKey, TEXT("EnableDHCP"), (pDhcp->Flags & DHCP_ENABLED_FL) ? 1 : 0);
AddrToString(pDhcp->IPAddr, Buffer);
fStatus = SetRegSZValue(hKey, TEXT("DhcpIPAddress"), Buffer);
DEBUGMSG (ZONE_WARN, (TEXT("\tSetDhcpConfig: set IPAddr %X\r\n"),
pDhcp->IPAddr));
if (fStatus) {
AddrToString(pDhcp->SubnetMask, Buffer);
SetRegSZValue(hKey, TEXT("DhcpSubnetMask"), Buffer);
AddrToString(pDhcp->DhcpServer, Buffer);
SetRegSZValue(hKey, TEXT("DhcpServer"), Buffer);
AddrToString(pDhcp->Gateway, Buffer);
SetRegSZValue(hKey, TEXT("DhcpDefaultGateway"), Buffer);
Buffer[0] = Buffer[1] = TEXT('\0');
i = 0;
if (pDhcp->DNS[0]) {
AddrToString(pDhcp->DNS[0], Buffer);
i = _tcslen(Buffer) + 1;
if (pDhcp->DNS[1]) {
AddrToString(pDhcp->DNS[1], &Buffer[i]);
i += _tcslen(&Buffer[i]) + 1;
}
Buffer[i] = TEXT('\0');
}
// we want: dns1\0dns2\0\0
SetRegMultiSZValue(hKey, TEXT("DhcpDNS"), Buffer);
Buffer[0] = Buffer[1] = TEXT('\0');
i = 0;
if (pDhcp->WinsServer[0]) {
AddrToString(pDhcp->WinsServer[0], Buffer);
i = _tcslen(Buffer) + 1;
if (pDhcp->WinsServer[1]) {
AddrToString(pDhcp->WinsServer[1], &Buffer[i]);
i += _tcslen(&Buffer[i]) + 1;
}
Buffer[i] = TEXT('\0');
}
// we want: wins1\0wins2\0\0
SetRegMultiSZValue(hKey, TEXT("DhcpWINS"), Buffer);
// Set Lease Times
SetRegDWORDValue(hKey, TEXT("LeaseObtainedLow"),
pDhcp->LeaseObtained.dwLowDateTime);
SetRegDWORDValue(hKey, TEXT("LeaseObtainedHigh"),
pDhcp->LeaseObtained.dwHighDateTime);
DEBUGMSG (ZONE_WARN,
(TEXT("\tSetDhcpConfig: set LeaseObtained %x %x\r\n"),
pDhcp->LeaseObtained.dwHighDateTime,
pDhcp->LeaseObtained.dwLowDateTime));
SetRegDWORDValue(hKey, TEXT("Lease"), pDhcp->Lease);
// Set T1 & T2
SetRegDWORDValue(hKey, TEXT("T1"), pDhcp->T1);
SetRegDWORDValue(hKey, TEXT("T2"), pDhcp->T2);
DEBUGMSG (ZONE_WARN,
(TEXT("\tSetDhcpConfig: T1 %x T2 %x Lease %x\r\n"),
pDhcp->T1, pDhcp->T2, pDhcp->Lease));
// Store the list of params requested from server so we can tell
// if it has changed after a reboot.
SetRegBinaryValue(hKey,TEXT("PrevReqOptions"),pDhcp->ReqOptions,pDhcp->ReqOptions[0]+1);
}
// Save auto IP config state
if (pDhcp->Flags & AUTO_IP_ENABLED_FL) {
SetRegDWORDValue(hKey, TEXT("AutoSeed"), pDhcp->AutoSeed);
AddrToString(pDhcp->AutoIPAddr, Buffer);
SetRegSZValue(hKey, TEXT("AutoIP"), Buffer);
AddrToString(pDhcp->AutoSubnet, Buffer);
SetRegSZValue(hKey, TEXT("AutoSubnet"), Buffer);
AddrToString(pDhcp->AutoMask, Buffer);
SetRegSZValue(hKey, TEXT("AutoMask"), Buffer);
SetRegDWORDValue(hKey, TEXT("AutoInterval"), pDhcp->AutoInterval);
} else {
SetRegDWORDValue(hKey, TEXT("AutoCfg"), 0);
}
RegCloseKey (hKey);
} // if (hKey)
if (pDhcp->aDomainName[0]) {
_tcscpy (Buffer, COMM_REG_KEY);
_tcscat (Buffer, TEXT("TcpIp\\Parms"));
hRes = RegOpenKeyEx (HKEY_LOCAL_MACHINE, Buffer, 0, 0, &hKey);
if (ERROR_SUCCESS == hRes) {
if (-1 != mbstowcs(Buffer, &pDhcp->aDomainName[1],
pDhcp->aDomainName[0])) {
Buffer[pDhcp->aDomainName[0]]= (L'\0');
SetRegSZValue(hKey, TEXT("DNSDomain"), Buffer);
}
RegCloseKey(hKey);
}
}
DEBUGMSG (ZONE_INIT, (TEXT("-SetDhcpConfig:\r\n")));
return DHCP_SUCCESS;
} // SetDhcpConfig()
// assumes caller owns pDhcp->Lock
void TakeNetDown(DhcpInfo *pDhcp, BOOL fDiscardIPAddr, BOOL fRemoveAfdInterface) {
HKEY hKey;
RETAILMSG(1, (TEXT("*TakeNetDown: pDhcp 0x%x IP %X!\r\n"),
pDhcp, pDhcp->IPAddr));
pDhcp->ARPResult = ERROR_UNEXP_NET_ERR;
SetEvent(pDhcp->ARPEvent); // wake up any waiting threads
(*pfnIPSetNTEAddr)((ushort)pDhcp->NteContext, NULL, 0, 0, 0);
if (fRemoveAfdInterface) {
CallAfd(AddInterface)(pDhcp->Name, pDhcp->Nte, pDhcp->NteContext,
ADD_INTF_DELETE_FL, pDhcp->IPAddr, pDhcp->SubnetMask, 0, NULL, 0, NULL);
}
if (fDiscardIPAddr) {
pDhcp->IPAddr = 0;
// Delete the IPAddr.
hKey = OpenDHCPKey(pDhcp);
if (hKey) {
RegDeleteValue(hKey, TEXT("DhcpIPAddress"));
RegCloseKey (hKey);
}
}
} // TakeNetDown()
// assumes caller has v_GlobalListLock
void PutInWorkerQ(DhcpInfo *pDhcp) {
HANDLE hWorkerThrd;
DWORD ThreadId;
pDhcp->pNext = v_pWaitingList;
v_pWaitingList = pDhcp;
// if there is already a worker thread we're done
if (! v_fWorkerThread) {
v_fWorkerThread = TRUE;
hWorkerThrd = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)DhcpWorkerThread, NULL, 0,
&ThreadId);
if (hWorkerThrd) {
CloseHandle(hWorkerThrd);
} else {
RETAILMSG(1,
(TEXT("!RequestDHCPAddr: can't create worker thread\r\n")));
}
}
} // PutInWorkerQ
//
// Close the Dhcp interface's socket if open and set it to NULL
// (Afd doesn't check the socket parameter, so we have to)
//
void
CloseDhcpSocket(
DhcpInfo *pDhcp
)
{
if (pDhcp->Socket) {
CallSock(Close) (pDhcp->Socket);
pDhcp->Socket = NULL;
}
}
// called when our lease has expired!
void ProcessExpire(DhcpInfo *pDhcp) {
DhcpInfo **ppDhcp;
DEBUGMSG(ZONE_TIMER|ZONE_WARN,
(TEXT("+ProcessExpire: pDhcp 0x%X\r\n"), pDhcp));
if (*(ppDhcp = _FindDhcp(pDhcp, NULL))) {
RETAILMSG(1, (TEXT("!Lease Time Expired, bringing net down %x\r\n"),
pDhcp));
*ppDhcp = pDhcp->pNext;
// take the interface down!
pDhcp->SFlags |= DHCPSTATE_LEASE_EXPIRE;
TakeNetDown(pDhcp, TRUE, TRUE);
ClearDHCPNTE(pDhcp);
CloseDhcpSocket(pDhcp);
PutInWorkerQ(pDhcp);
CTEFreeLock(&v_GlobalListLock, 0);
CTEFreeLock(&pDhcp->Lock, 0);
} else
CTEFreeLock(&v_GlobalListLock, 0);
DEBUGMSG(ZONE_TIMER, (TEXT("-ProcessExpire: pDhcp 0x%X\r\n"),
pDhcp));
} // ProcessExpire()
void CalcMidwayTime(DhcpInfo *pDhcp, int End, CTEEventRtn Rtn1,
CTEEventRtn Rtn2) {
FILETIME CurTime, EndTime, TempTime;
// calc Expire time, if > 1 min restart T1 timer
EndTime.dwLowDateTime = End;
EndTime.dwHighDateTime = 0;
mul64_32_64(&EndTime, TEN_M, &EndTime);
add64_64_64(&pDhcp->LeaseObtained, &EndTime, &EndTime);
GetCurrentFT(&CurTime);
if (CompareFileTime(&CurTime, &EndTime) >= 0) {
DEBUGMSG(ZONE_TIMER,
(TEXT("*CalcMidwayTime: late already! start 2nd timer %x %x\r\n"),
EndTime.dwHighDateTime, EndTime.dwLowDateTime));
// start next timer
CTEStartFTimer(&pDhcp->Timer, EndTime,
(CTEEventRtn)Rtn2, pDhcp);
} else {
sub64_64_64(&EndTime, &CurTime, &TempTime);
DEBUGMSG(ZONE_TIMER,
(TEXT("*CalcMidwayTime: CurTime %x %x Endtime %x %x dt %x %x\r\n"),
CurTime.dwHighDateTime, CurTime.dwLowDateTime,
EndTime.dwHighDateTime, EndTime.dwLowDateTime,
TempTime.dwHighDateTime, TempTime.dwLowDateTime));
// if more than 1 min remain, restart timer
// otherwise start the next timer
if (TempTime.dwHighDateTime > 0 ||
(TempTime.dwHighDateTime == 0 &&
TempTime.dwLowDateTime >= (60 * TEN_M))) {
div64_32_64(&TempTime, 2, &TempTime);
add64_64_64(&CurTime, &TempTime, &TempTime);
DEBUGMSG(ZONE_TIMER,
(TEXT("*CalcMidwayTime: starting timer for %x %x\r\n"),
TempTime.dwHighDateTime, TempTime.dwLowDateTime));
// restart the timer
CTEStartFTimer(&pDhcp->Timer, TempTime,
(CTEEventRtn)Rtn1, pDhcp);
} else {
DEBUGMSG(ZONE_TIMER,
(TEXT("*CalcMidwayTime: starting 2nd timer for %x %x\r\n"),
EndTime.dwHighDateTime, EndTime.dwLowDateTime));
// start next timer
CTEStartFTimer(&pDhcp->Timer, EndTime,
(CTEEventRtn)Rtn2, pDhcp);
}
}
} // CalcMidwayTime()
void CalcT1Time(DhcpInfo *pDhcp) {
FILETIME Ft;
Ft.dwLowDateTime = pDhcp->T1;
Ft.dwHighDateTime = 0;
mul64_32_64(&Ft, TEN_M, &Ft);
add64_64_64(&pDhcp->LeaseObtained, &Ft, &Ft);
// Start T1 timer
DEBUGMSG(ZONE_TIMER, (TEXT("*CalcT1Time: init LO %x %x , T1 %x %x\r\n"),
pDhcp->LeaseObtained.dwHighDateTime, pDhcp->LeaseObtained.dwLowDateTime,
Ft.dwHighDateTime, Ft.dwLowDateTime));
CTEStartFTimer(&pDhcp->Timer, Ft, (CTEEventRtn)ProcessT1, pDhcp);
} // CalcT1Time()
STATUS DhcpInitSock(DhcpInfo *pInfo, int SrcIP) {
SOCKADDR_IN SockAddr;
STATUS Status = DHCP_SUCCESS;
LPSOCK_INFO Sock;
DEBUGMSG(ZONE_INIT, (TEXT("+DhcpInitSock: pInfo 0x%X\r\n"),
pInfo));
memset ((char *)&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = net_short(DHCP_CLIENT_PORT);
SockAddr.sin_addr.S_un.S_addr = SrcIP; // net_long(0);
// set flag that this is an internal socket
Sock = (LPSOCK_INFO) CallAfd(Socket)
(0x80000000 | AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (Sock) {
int i = 1;
if (SOCKET_ERROR == CallSock(SetOption)(Sock, SOL_SOCKET,
SO_REUSEADDR, &i, sizeof(i), NULL) ||
SOCKET_ERROR == CallSock(SetOption)(Sock, SOL_SOCKET,
SO_BROADCAST, &i, sizeof(i), NULL) ||
SOCKET_ERROR == CallSock(Bind)(Sock, (SOCKADDR *)&SockAddr,
sizeof(SockAddr), (struct CRITICAL_SECTION *)0xffffffff))
{
Status = GetLastError();
DEBUGMSG(ZONE_WARN | ZONE_ERROR,
(TEXT("\t!DhcpInitSock: failure %d\r\n"),
Status));
CallSock(Close) (Sock);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -