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

📄 dhcp.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
	int offset;
	int retry = 0;

	offset = InitDhcpPacket(DHCPDISCOVER, 1);
	/* End Option */
	dhcppacket.options[offset] = DHCP_END_OPTION;
	
	while (retry < 4)
	{
		int timeout = DHCP_TIMEOUT;
		int len;
		if (SendIPBroadcast() != DHCP_OK)
		{
			printf("DHCP: Send Discovery Broadcast error!\n");
			return DHCP_ERROR;
		}
		bzero((void *) &recv_packet, sizeof(s_dhcppacket));
		if (readable_timeo(sockfd, timeout) <= 0)
		{
			printf("DHCP: Timeout waiting for Offer\n");
		}
		else 
		{
			if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0) 
			{
				perror("recvfrom");
				return DHCP_ERROR;
			}
			printf("DHCP: Got one message to Discovery\n");
			if (recv_packet.op == BOOT_REPLY &&
				recv_packet.xid == client_xid &&
				ParseDhcpOption() == DHCPOFFER)
			{
				return DHCP_OK;
			}
		}
		timeout *= 2;
		retry++;
	}
	printf("DHCP: DO Discovery -- no response\n");
	return DHCP_RETRY;
}

int DoDhcpRequest(int sockfd)
{
	int offset;
	int retry = 0;
	int macCount = 0;
	int timeout,lasttime;
	int isRetry = 0;
	unsigned int timeBegin,timeEnd;
	offset = InitDhcpPacket(DHCPREQUEST, 1);

	/* server identifier */
	dhcppacket.options[offset++] = DHCP_SERVERID_OPTION;
	dhcppacket.options[offset++] = 4;
	memcpy(dhcppacket.options + offset, &dhcp_server, 4);
	offset += 4;

	/* requested IP address */
	dhcppacket.options[offset++] = DHCP_REQIP_OPTION;
	dhcppacket.options[offset++] = 4;
	memcpy(dhcppacket.options + offset, &dhcp_allocated, 4);
	offset += 4;

	/* End Option */
	dhcppacket.options[offset] = DHCP_END_OPTION;
	timeout = DHCP_TIMEOUT;
	lasttime = DHCP_TIMEOUT;
	while (retry < 4)
	{
		int len;
		isRetry = 0;
		timeBegin = tickGet();
		
		if (SendIPBroadcast() != DHCP_OK)
		{
			return DHCP_ERROR;
		}
		bzero((void *) &recv_packet, sizeof(s_dhcppacket));
		if (readable_timeo(sockfd, timeout) <= 0)
		{
			printf("DHCP: Timeout waiting for Ack\n");
		}
		else 
		{	
			
			if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0) 
			{
				perror("recvfrom");
				return DHCP_ERROR;
			}
			/*** all the phone's xid is the same
			if(recv_packet.xid !=client_xid)
			{
				printf("xid error!\n");
				 return DHCP_RETRY;
			}
			****/
			/***check if receive dhcp packets is not send to this mac*****/
			timeEnd= tickGet();
			for(macCount = 0;macCount <MAC_ADD_LEN;macCount ++)
			{
				
				printf("0x%x\n",mac_addr.MACByte[macCount]);
				printf("0x%x\n",recv_packet.chaddr[macCount]);
				
				if(mac_addr.MACByte[macCount] != recv_packet.chaddr[macCount])
				{
					printf("This is not for my MAC\n");
					timeout -= (timeEnd -timeBegin)/100;
					if(timeout > 0)
					{
						isRetry = 1;
						break;
					}
				}
				
			}
			if(isRetry)
				continue;
			
			
			if (recv_packet.op == BOOT_REPLY &&	recv_packet.xid == client_xid)
			{
				int ret = ParseDhcpOption();
				if (ret == DHCPACK)
				{
					return DHCP_OK;
				}
				else if (ret == DHCPNAK)
				{
					return DHCP_RETRY;
				}
			}
		}
			
			
		timeout = 2*lasttime;
		lasttime = timeout;
		retry++;
	}
	return DHCP_RETRY;
}

int RenewDhcpLease()
{
	int clientSock;
	int result;
	unsigned short renew_ok = 1;
	unsigned int T1, T2;

	for (;;)
	{
		if (!renew_ok)
		{
			/* Time over */
			break;
		}
		T1 = dhcp_lease / 2;
		T2 = dhcp_lease * 4 / 5;
		taskDelay((T1 - 5) * sysClkRateGet());
		
		semTake(dhcpClientSem, WAIT_FOREVER);
		if ((clientSock = InitDhcpClientSock()) != DHCP_ERROR)
		{
			InitDhcpServerAddr(0);
			if ((result = RequestPreAddr(clientSock, 0)) == DHCP_OK)
			{
				renew_ok = 1;
				close(clientSock);
				semGive(dhcpClientSem);
				continue;
			}
			else if (result == DHCP_RETRY)
			{
				close(clientSock);
				semGive(dhcpClientSem);
			}
			else 
			{
				renew_ok = 0;
				close(clientSock);
				semGive(dhcpClientSem);
				continue;
			}
		}
		semGive(dhcpClientSem);
		
		taskDelay((T2 - T1 - 10) * sysClkRateGet());

		semTake(dhcpClientSem, WAIT_FOREVER);
		if ((clientSock = InitDhcpClientSock()) != DHCP_ERROR)
		{
			InitDhcpServerAddr(1);
			if ((result = RequestPreAddr(clientSock, 1)) == DHCP_OK)
			{
				renew_ok = 1;
				close(clientSock);
				semGive(dhcpClientSem);
				continue;
			}
			else if (result == DHCP_RETRY)
			{
				close(clientSock);
				semGive(dhcpClientSem);
			}
			else
			{
				renew_ok = 0;
				close(clientSock);
				semGive(dhcpClientSem);
				continue;
			}
		}
		semGive(dhcpClientSem);
		
		renew_ok = 0;
		taskDelay((dhcp_lease - T2) * sysClkRateGet());
	}
	/* 需要通知用户IP地址过期 */
	renew_task_id = 0;
}

int RequestPreAddr(int sockfd, unsigned char broadcast)
{
	int offset;
	int retry = 0;

	client_xid = htonl(rand());

	offset = InitDhcpPacket(DHCPREQUEST, broadcast);

	dhcppacket.options[offset] = DHCP_END_OPTION;

	dhcppacket.ciaddr.s_addr = dhcp_allocated;

	while (retry < 4)
	{
		int timeout = DHCP_TIMEOUT;
		int len;
		if (broadcast)
		{
			if (SendIPBroadcast() != DHCP_OK)
			{
				return DHCP_ERROR;
			}
		}
		else if ((len = sendto(sockfd, (void *) &dhcppacket, DHCP_MIN_LEN, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))) < 0)
		{
			perror("sendto");
			return DHCP_ERROR;
		}
		bzero((void *) &recv_packet, sizeof(s_dhcppacket));
		if (readable_timeo(sockfd, timeout) <= 0)
		{
			return DHCP_ERROR;
		}
		else 
		{
			if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0) 
			{
				perror("recvfrom");
				return DHCP_ERROR;
			}
			if (recv_packet.op == BOOT_REPLY &&	recv_packet.xid == client_xid)
			{
				int ret = ParseDhcpOption();
				if (ret == DHCPACK)
				{
					return DHCP_OK;
				}
				else
				{
					return DHCP_ERROR;
				}
			}
			timeout *= 2;
			retry++;
		}
	}
	return DHCP_RETRY;
}


/*
* 断开连接后重新申请原先的地址
*/
int InitWithKnownIP()
{
	int offset;
	int retry = 0;
	int result, sockfd;

	semTake(dhcpClientSem, WAIT_FOREVER);

	if ((sockfd = InitDhcpClientSock()) == DHCP_ERROR)
	{
		semGive(dhcpClientSem);
		return DHCP_ERROR;
	}

	offset = InitDhcpPacket(DHCPREQUEST, 1);

	/* requested IP address */
	dhcppacket.options[offset++] = DHCP_REQIP_OPTION;
	dhcppacket.options[offset++] = 4;
	memcpy(dhcppacket.options + offset, &dhcp_allocated, 4);
	offset += 4;

	/* End Option */
	dhcppacket.options[offset] = DHCP_END_OPTION;

	result = DHCP_RETRY;
	while (retry < 4 && result == DHCP_RETRY)
	{
		int timeout = DHCP_TIMEOUT;
		int len;
		if (SendIPBroadcast() != DHCP_OK)
		{
			result = DHCP_ERROR;
		}
		bzero((void *) &recv_packet, sizeof(s_dhcppacket));
		if (readable_timeo(sockfd, timeout) <= 0)
		{
			printf("DHCP: Init Reboot Timeout for Ack\n");
		}
		else 
		{
			if ((len = recvfrom(sockfd, (void *) &recv_packet, DHCP_MIN_LEN, 0, NULL, NULL)) < 0) 
			{
				perror("recvfrom");
				result = DHCP_ERROR;
			}
			if (recv_packet.op == BOOT_REPLY &&	recv_packet.xid == client_xid)
			{
				int ret = ParseDhcpOption();
				if (ret == DHCPACK)
				{
					result = DHCP_OK;
				}
				else if (ret == DHCPNAK)
				{
					result = DHCP_ERROR;
				}
			}
		}
		timeout *= 2;
		retry++;
	}
	close(sockfd);
	semGive(dhcpClientSem);
	
	if (result == DHCP_OK && renew_task_id != 0)
	{
		taskDelete(renew_task_id);
		renew_task_id = taskSpawn( "tDhcpRenew",150,0,4096,(FUNCPTR)RenewDhcpLease,0,0,0,0,0,0,0,0,0,0);
	}
	else if (result == DHCP_ERROR)
	{
		return DHCP_ERROR;
	}
	return DHCP_OK;
}

⌨️ 快捷键说明

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