dhcp.c
来自「wince下的源代码集合打包」· C语言 代码 · 共 1,724 行 · 第 1/4 页
C
1,724 行
HKEYOpenDHCPKey( 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->Lockvoid 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_GlobalListLockvoid 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)//voidCloseDhcpSocket( 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?