⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhcp.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 4 页
字号:


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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -