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

📄 dhcpc.c

📁 Linux下DHCP Client的实现。
💻 C
📖 第 1 页 / 共 5 页
字号:
					if (thaddr)
						memcpy(thaddr, reparp.sha, 6);
					return ARP_HAVE_SAME_ADDR;
					//break;
				}
			}
		}
		else
		{
			break;
		}
		//break;
	}
	close(LpfSd);
	if (result>=25)
	{
		return ARP_ERROR;
	}
	return ARP_SUCCESS;
}

void DHCPClientFillReturnMsg(
		DhcpcMsgConfigStatus_t *Msg,
		char *szIfName,
		uint32_t ulMsgType,
		uint32_t ulConfigStatus
	)
{
	memset(Msg, 0, sizeof(DhcpcMsgConfigStatus_t));
	Msg->ulMsgType = ulMsgType;
	strcpy(Msg->szIfName, szIfName);
	Msg->ulConfigStatus = ulConfigStatus;
}

bool_t DHCPClientSendPktToConfigServer(
		DhcpcMsgConfigStatus_t *Msg,
		struct sockaddr_in saddr,
		int len
	)
{
	if (-1 == (sendto(s_iConfigServerSocket, 
		(char *)Msg, 
		sizeof(DhcpcMsgConfigStatus_t),
		0,
		(struct sockaddr *)&saddr,
		len)))
	{
		perror("send msg to config server error");
		return FALSE;
	}
	return TRUE;
}

//////////////////////////////////////////////////////////////////
//					Functions
//////////////////////////////////////////////////////////////////
void DHCPClientPrintAllTransActionId(void)
{
	DHCPClientBlock_t *pTmpBlock = NULL;
	for (pTmpBlock=pDHCPClientCtxtBlockHead;pTmpBlock!=NULL;pTmpBlock=pTmpBlock->next)
	{
		printf("Interface name = %s\n", pTmpBlock->cszIfName);
	}
}

void DHCPClientDeleteTimer(char *szIfName)
{
	DHCPWAITEvent_t *pTmpBlock = pDHCPClientTimerHead;
	DHCPWAITEvent_t *pLastBlock = pDHCPClientTimerHead;
	
	if (pDHCPClientTimerHead == pDHCPClientTimerTail)
	{
		//only one node
		printf("In DHCPClientDeleteTimer Only One Node!******************************\n");
		free(pDHCPClientTimerHead);
		pDHCPClientTimerHead = NULL;
		pDHCPClientTimerTail = NULL;
		return;
	}
	
	for (;pTmpBlock; pTmpBlock = pTmpBlock->Next)
	{
		if (0 == strcmp(pTmpBlock->cszIfName, szIfName))
		{
			if (NULL == pTmpBlock->Next)
			{
				//tail node
				while (pLastBlock->Next != pTmpBlock)
					pLastBlock = pLastBlock->Next;
				free(pTmpBlock);
				pLastBlock->Next = NULL;
				pDHCPClientTimerTail = pLastBlock;
				return ;
			}
			else
			{
				if (pDHCPClientTimerHead == pTmpBlock) //head node
				{
					pTmpBlock = pTmpBlock->Next;
					free(pDHCPClientTimerHead);
					pDHCPClientTimerHead = pTmpBlock;
					return;
				}
				while (pLastBlock->Next != pTmpBlock)
					pLastBlock = pLastBlock->Next;
				pLastBlock->Next = pLastBlock->Next->Next;
				return ;
			}
		}		
	}
}

int DHCPClientInsertTimer(DHCPWAITEvent_t *pTimer)
{
	//DHCPWAITEvent_t *insert = pTimer;
	DHCPWAITEvent_t *block = pDHCPClientTimerHead;
	if (NULL == pTimer)
	{
		return FALSE;
	}
	for (;block; block=block->Next)
	{
		//if (block->iIfIndex == pTimer->iIfIndex)
		if (0 == strcmp(block->cszIfName, pTimer->cszIfName))
			return FALSE;
	}
	if (NULL == pDHCPClientTimerHead)
	{
		pDHCPClientTimerHead = pDHCPClientTimerTail = pTimer;		
	}
	else
	{
		pDHCPClientTimerTail->Next = pTimer;
		pDHCPClientTimerTail = pTimer;
	}
	//pDHCPClientTimerCurrent = pDHCPClientTimerTail;
	return TRUE;
}

#define MAX_TRANSACTIONID	16
int DHCPClientInsertBlock(DHCPClientBlock_t *pCurBlock)
{
	int num = 0;
	DHCPClientBlock_t *DelBlock = NULL;
	DHCPClientBlock_t *block = pDHCPClientCtxtBlockHead;
	for (;block;block=block->next)
	{
		num++;
		//change judge interface index to interface name, because interface index can == -1
		//if (block->uiIfIndex == pCurBlock->uiIfIndex)
		if (0 == strcmp(block->cszIfName, pCurBlock->cszIfName))
		{
			return FALSE;
		}
	}
	if (NULL == pDHCPClientCtxtBlockHead)
	{
		pDHCPClientCtxtBlockHead = pDHCPClientCtxtBlockTail = pCurBlock;
		pDHCPClientCtxtBlockHead->next = NULL;
		return TRUE;
	}
	if (num > MAX_TRANSACTIONID)
	{
		//when list is too long then del some node
		//xhema 20041119 must modify don't delete node, but use other idea
		printf("over max num!\n");
		DelBlock = pDHCPClientCtxtBlockHead;
		pDHCPClientCtxtBlockHead = pDHCPClientCtxtBlockHead->next;
		free(DelBlock);
	}
	pDHCPClientCtxtBlockTail->next = pCurBlock;
	pDHCPClientCtxtBlockTail = pCurBlock;

	return TRUE;
}

uint32_t  DHCPClientRemoveInterface(char *szIfName)
{
	DHCPClientBlock_t *pTmpBlock = pDHCPClientCtxtBlockHead;
	DHCPClientBlock_t *pLastBlock = pDHCPClientCtxtBlockHead;
	if (pDHCPClientCtxtBlockHead == pDHCPClientCtxtBlockTail)
	{
		//only one node
		free(pDHCPClientCtxtBlockHead);
		pDHCPClientCtxtBlockHead = pDHCPClientCtxtBlockTail = NULL;
		g_pDHCPClientCurrent = NULL;
		return TRUE;
	}
	for (; pTmpBlock; pTmpBlock = pTmpBlock->next)
	{
		if (0 == (strcmp(pTmpBlock->cszIfName, szIfName)))
		{
			printf("In DHCPClientRemoveInterface: %s\n", pTmpBlock->cszIfName);
			if (NULL == pTmpBlock->next)
			{
				//tail node
				while (pLastBlock->next != pTmpBlock)
					pLastBlock = pLastBlock->next;
				free(pTmpBlock);
				pLastBlock->next = NULL;
				pDHCPClientCtxtBlockTail = pLastBlock;
				return TRUE;
			}
			else
			{
				printf("Next != NULL\n");
				if (pDHCPClientCtxtBlockHead == pTmpBlock)
				{
					pTmpBlock = pTmpBlock->next;
					free(pDHCPClientCtxtBlockHead);
					pDHCPClientCtxtBlockHead = pTmpBlock;
					return TRUE;
				}
				while (pLastBlock->next != pTmpBlock)
					pLastBlock = pLastBlock->next;
				pLastBlock->next = pLastBlock->next->next;
				return TRUE;
			}
		}		
	}
	return DHCPC_STATUS_IF_MISSED;
}

uint32_t DHCPClientFillInterfaceName(DhcpcMsgInterfaceList_t *ListMsg)
{
	int i = 0;
	DHCPClientBlock_t *pTmpBlock = pDHCPClientCtxtBlockHead;
	for (; pTmpBlock; pTmpBlock = pTmpBlock->next)
	{
		strcpy(ListMsg->szIfName[i++], pTmpBlock->cszIfName);
	}
	return TRUE;
}
uint32_t DHCPClientCurrentIfaceCount(void)
{
	uint32_t Num = 0;
	DHCPClientBlock_t *pTmpBlock = pDHCPClientCtxtBlockHead;
	for (;pTmpBlock; pTmpBlock = pTmpBlock->next)
	{
		Num++;
	}
	return Num;
}

DHCPClientBlock_t *DHCPClientIfaceIsAllocByIfName(char *szIfName)
{
	DHCPClientBlock_t *pTmpBlock = pDHCPClientCtxtBlockHead;
	for (;pTmpBlock; pTmpBlock = pTmpBlock->next)
	{
		if (0 == strcmp(szIfName, pTmpBlock->cszIfName))
			break;
	}
	return pTmpBlock;
}
		
		
DHCPClientBlock_t *DHCPClientIfaceIsAllocByIndex(
		int uiIfIndex,
		bool_t bActive,
		bool_t bIgnoreActive
	)
{
	DHCPClientBlock_t *TmpBlock = pDHCPClientCtxtBlockHead;
	for (;TmpBlock;TmpBlock=TmpBlock->next)
	{
		if (bIgnoreActive)
		{
			if (uiIfIndex == TmpBlock->uiIfIndex)
			{
				break;
			}
		}
		else
		{
			if ((uiIfIndex == TmpBlock->uiIfIndex) &&
				(bActive == TmpBlock->bIfActive))
			{
				break;
			}
		}
	}
	return TmpBlock;
}


void DHCPClientFillFunctions(struct DHCPClientFunctions *pEntry)
{
	pEntry->DHCPNetworkConfig = DHCPClientDefaultConfig;
	pEntry->FillOptions = DHCPCFillOptions;
	pEntry->SendPacket = DHCPClientSendPacket;
	return;
}

void DHCPClientTimerProc(void)
{
	DHCPWAITEvent_t *pEvent= pDHCPClientTimerHead;
	
	for (; pEvent!=NULL; pEvent=pEvent->Next)
	{
		//judge this interface whether up, update it's status
		DHCPClientUpdateIfStatus(pEvent);
		//
		if (TRUE == pEvent->bStartWaitEvent)
		{
			if ((CurrentTime - pEvent->iWaitStartTime) >= pEvent->iWaitTimeOutTime)
			{
				switch (pEvent->EventType)
				{
				case WAIT_DISCOVER:
					printf("discover timeout***********************************\n");
					if (-1 == DHCPClientDiscoverTimeoutProcess(pEvent, pEvent->pPointToBlock))
					{
						printf("Timeout Set Network error....\n");
					}
					break;
				case WAIT_REQUEST:
					printf("Request timeout**********************************\n");
					if (-1 == DHCPClientRequestTimeoutProcess(pEvent))
					{
						printf("Request timeout error....\n");
					}
					break;
				case WAIT_INFORM:
					printf("now inform is timeout.... Event = %d  Time = %d\n", pEvent->EventType, pEvent->iWaitStartTime);
					pEvent->bStartWaitEvent = FALSE;
					break;
				default:
					break;
				}
			}
		}
		//if lease time is over half then send request pkt
		if (NULL!=pEvent->pPointToBlock)
		{
			if ((pEvent->pPointToBlock->bDHCPClientEnabled) &&
				(FALSE == pEvent->pPointToBlock->bRequestToConnect))
			{
				if ((pEvent->pPointToBlock->ulStartLeaseTime!=0 && 
					pEvent->pPointToBlock->ulLeasedTime!=0) &&
					((CurrentTime - pEvent->pPointToBlock->ulStartLeaseTime) 
					>= pEvent->pPointToBlock->ulLeasedTime/2)
				   )
				{
					//printf("**********************Lease time is over half!********************\n");
					pEvent->pPointToBlock->CurrentState = DHCP_CLIENT_RENEW;
					pEvent->pPointToBlock->ulStartLeaseTime = 0;	
					TimerStart(
						pEvent->pPointToBlock->pTimer, 
						DEFAULT_REQUEST_TIMEOUT, 
						WAIT_REQUEST);
					if (FALSE == DHCPClientSendDHCPRequest(pEvent->pPointToBlock))
					{
						printf("Request is error\n");
					}
				}
				else if ((TRUE == pEvent->fWillSend) &&
							((CurrentTime - pEvent->uiStartLeaseTime) >= pEvent->pPointToBlock->ulLeasedTime)
						)
				{
					//printf("**********************Lease time is over half  ()()()()!********************\n");
					pEvent->pPointToBlock->CurrentState = DHCP_CLIENT_RENEW;
					pEvent->uiStartLeaseTime = CurrentTime;
					pEvent->fWillSend = FALSE;
					TimerStart(
						pEvent->pPointToBlock->pTimer, 
						0, 
						WAIT_REQUEST);
					if (FALSE == DHCPClientSendDHCPRequest(pEvent->pPointToBlock))
					{
						printf("Request is error\n");
					}
				}
			}
		}
		//DHCP Client change to disable but still want to get DHCP Server's IP Setting
		if (TRUE == pEvent->pPointToBlock->bRequestToConnect)
		{
			//(int) change unsigned int style to int
			if ((int)(CurrentTime-pEvent->pPointToBlock->ulLeaveTime)>0)
			{
				#define INTERVAL_TIME 60;
				pEvent->pPointToBlock->ulLeaveTime += INTERVAL_TIME;
				DHCPClientSendDHCPDiscover(pEvent->pPointToBlock);
				return;
			}
		}
		//DHCP Client will send arp packet when interface is BOUND states (one minute)
		if (DHCP_CLIENT_BOUND == pEvent->pPointToBlock->CurrentState)
		{
			if ((int)(CurrentTime-pEvent->pPointToBlock->ulLeaveArpSendTime)>0)
			{
				#define SEND_ARP_INTERVAL_TIME 60;
				char desthwaddr[6] = {0};
				ipaddr addr1;
				ArpReplyType_t ArpReply;
				pEvent->pPointToBlock->ulLeaveArpSendTime += SEND_ARP_INTERVAL_TIME;
				memset(desthwaddr, 0, 6);
				addr1 = inet_addr("127.0.0.1");
				pEvent->pPointToBlock->CurrentState = DHCP_CLIENT_ARP_AWAIT;
				ArpReply = DHCPClientSendArp(pEvent->pPointToBlock->cszIfName, 
					pEvent->pPointToBlock->aucHwAddress, desthwaddr, 
					addr1, pEvent->pPointToBlock->LeasedIpAddress);
				printf("ArpReply = %d\n", ArpReply);
				if ((ARP_SUCCESS == ArpReply) || (ARP_ERROR == ArpReply))
				{
					pEvent->pPointToBlock->CurrentState = DHCP_CLIENT_BOUND;
				}
				if (ArpReply == ARP_HAVE_SAME_ADDR)
				{
					if (0==memcmp(pEvent->pPointToBlock->aucHwAddress, desthwaddr, 6))
					{
						//the eth addr is local machine, NO ip clash
						printf("arp is not clash\n");
						pEvent->pPointToBlock->CurrentState = DHCP_CLIENT_BOUND;
					}
					else
					{
						//ip clash
						printf("ip clash!!!!!\n");
						DHCPClientSendDHCPDecline(pEvent->pPointToBlock);    //refuse this addr
						sleep(1);
						pEvent->pPointToBlock->CurrentState = DHCP_CLIENT_INITIALIZED;
						TimerStart(pEvent,
							DEFAULT_DISCOVER_TIMEOUT, 
							WAIT_DISCOVER);
						pEvent->pPointToBlock->CurrentState = DHCP_CLIENT_SELECT;			
						DHCPClientSendDHCPDiscover(pEvent->pPointToBlock);
						return;
					}
				}
			}
		}
	}
}

///////////////////////////////////////////////////////////////////////////////
// IP converter routines
///////////////////////////////////////////////////////////////////////////////
bool_t IsValidIP(in_addr_t ulIP)
{
	uint8_t uchFirstOctet;
	uint8_t uchLastOctet;

	ulIP = ntohl(ulIP);

	uchFirstOctet	= (uint8_t)((ulIP>>24)&0x000000FFL);
	uchLastOctet	= (uint8_t)(ulIP&0x000000FFL);

	if (uchFirstOctet<1 || uchFirstOctet>223)
	{
		//TRACE("First octet of IP must be between 1 and 223\n");
		return FALSE;
	}
	if (uchFirstOctet==127)
	{
		//TRACE("First octet 127 is reserved for loop back\n");
		return FALSE;
	}
	if (uchLastOctet==255 || uchLastOctet==0)
	{
		//TRACE("Last octet 0 and 255 are reserved for broadcast\n");
		return FALSE;
	}
	return TRUE;
}

bool_t InterfaceGatewaySet(const char *cszIfName, in_addr_t ulGateway)
{
	struct rtentry RouteEntry = {0};
	struct sockaddr_in *pSockAddrIn
		= (struct sockaddr_in *)&RouteEntry.rt_gateway;

	// remove all exist gateway
	RouteEntry.rt_dst.sa_family = 2;
	RouteEntry.rt_flags = RTF_UP | RTF_GATEWAY;
	RouteEntry.rt_dev = (char*)cszIfName;

⌨️ 快捷键说明

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