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

📄 dhcp.c

📁 Wiznet iRadio Source
💻 C
📖 第 1 页 / 共 2 页
字号:
	ip[0] = 255;
	ip[1] = 255;
	ip[2] = 255;
	ip[3] = 255;

//	MyPrintf("> send DHCP_Decline\r\n");

	sendto(s, (u8 *)(&MSG.op), RIP_MSG_SIZE, ip, DHCP_SERVER_PORT);
}

/*
*********************************************************************************************************
*              PARSE REPLY MSG
*
* Description: This function parses the reply message from DHCP server.
* Arguments  : s      - is a socket number.
*              length - is a size data to receive.
* Returns    : None.
* Note       : 
*********************************************************************************************************
*/
char parseDHCPMSG(u8 s, u16 length)
{
	u8 svr_addr[6];
	u16  svr_port;

	u16 i, len;
	u8 * p;
	u8 * e;
	u8 type, opt_len;

	len = recvfrom(s, (u8 *)&MSG.op, length, svr_addr, &svr_port);
	
	if (svr_port == DHCP_SERVER_PORT) {

		for (i = 0; i < 6; i++)
			if (MSG.chaddr[i] != MAC[i]) {
				type = 0;
				goto PARSE_END;
			}

		for (i = 0; i < 4; i++) {
			Config_Msg.Lip[i] = MSG.yiaddr[i];
		}
		
		type = 0;
		p = (u8 *)(&MSG.op);
		p = p + 240;
		e = p + (len - 240);

		while ( p < e ) {
			switch ( *p ) {

			case endOption :
				goto PARSE_END;
       			case padOption :
				p++;
				break;
			case dhcpMessageType :
				p++;
				p++;
				type = *p++;
				break;
			case subnetMask :
				p++;
				p++;
				for (i = 0; i < 4; i++)	 Config_Msg.Sn[i] = *p++;
				break;
			case routersOnSubnet :
				p++;
				opt_len = *p++;       
				for (i = 0; i < 4; i++)	Config_Msg.Gw[i] = *p++;
				for (i = 0; i < (opt_len-4); i++) p++;
				break;
			case dns :
				p++;                  
				opt_len = *p++;       
				for (i = 0; i < 4; i++)	Config_Msg.DNS_SIP[i] = *p++;
				for (i = 0; i < (opt_len-4); i++) p++;
				break;
				
			case dhcpIPaddrLeaseTime :
				p++;
				opt_len = *p++;
				lease_time.cVal[3] = *p++;
				lease_time.cVal[2] = *p++;
				lease_time.cVal[1] = *p++;
				lease_time.cVal[0] = *p++;
				break;

			case dhcpServerIdentifier :
				p++;
				opt_len = *p++;
				DHCP_SIP[0] = *p++;
				DHCP_SIP[1] = *p++;
				DHCP_SIP[2] = *p++;
				DHCP_SIP[3] = *p++;
				break;

			default :
				p++;
				opt_len = *p++;
				p += opt_len;
				break;
			} // switch
		} // while
	} // if

PARSE_END :
	return	type;
}

/*
*********************************************************************************************************
*              CHECK DHCP STATE
*
* Description: This function checks the state of DHCP.
* Arguments  : None.
* Returns    : None.
* Note       : 
*********************************************************************************************************
*/
void check_DHCP_state(void) 
{
	u16 len, i;
	u8 type, flag;
	u8 d_addr[4];
	
	type = 0;
	
	if ((len = getSn_RX_RSR(SOCK_DHCP)) > 0) {
		//cli();
		type = parseDHCPMSG(SOCK_DHCP, len);
		//sei();
	}
	
	switch ( dhcp_state ) {
		case STATE_DHCP_DISCOVER :
			if (type == DHCP_OFFER) {
				MyPrintf("< Receive DHCP_OFFER\r\n");
				
				for (i = 0; i < 4; i++) d_addr[i] = 0xff;
				send_DHCP_REQUEST(SOCK_DHCP, Cip, d_addr);
				
				dhcp_state = STATE_DHCP_REQUEST;
			} else check_Timeout();
		break;

		case STATE_DHCP_REQUEST :
			if (type == DHCP_ACK) {
				my_time = 0;
				
				MyPrintf("< Receive DHCP_ACK\r\n");
				
				if (check_leasedIP()) {
					iinchip_init();
					Set_network();
					for (i = 0; i < 12; i++) {
						EEP_Write(EEP_LIP+i, *(u8 *)(Config_Msg.Lip+i));
					}

					my_time = 0;
					next_time = my_time + DHCP_WAIT_TIME;
					retry_count = 0;
					dhcp_state = STATE_DHCP_LEASED;
				} else {
					my_time = 0;
					next_time = my_time + DHCP_WAIT_TIME1;
					retry_count = 0;
					//dhcp_state = STATE_DHCP_DISCOVER;
					dhcp_state = STATE_DHCP_LEASED;
					MyPrintf(": Recceived IP is invalid\r\n");
					
					iinchip_init();
					Set_Default();
					Set_network();
				}
			} else if (type == DHCP_NAK) {
				MyPrintf("< Receive DHCP_NACK\r\n");
				my_time = 0;
				next_time = my_time + DHCP_WAIT_TIME;
				retry_count = 0;
				dhcp_state = STATE_DHCP_DISCOVER;
			} else check_Timeout();
		break;

		case STATE_DHCP_LEASED :
			if ((lease_time.lVal != 0xffffffff) && ((lease_time.lVal/2) < my_time)) {
				
				MyPrintf("\r\nRenewal IP address ");

				type = 0;
				for (i = 0; i < 4; i++)	OLD_SIP[i] = Config_Msg.Lip[i];
				for (i = 0; i < 4; i++)	d_addr[i] = DHCP_SIP[i];
				
				DHCP_XID++;
				send_DHCP_REQUEST(SOCK_DHCP, Config_Msg.Lip, d_addr);
				dhcp_state = STATE_DHCP_REREQUEST;

				my_time = 0;
				next_time = my_time + DHCP_WAIT_TIME;
			}
		break;

		case STATE_DHCP_REREQUEST :
			if (type == DHCP_ACK) {
				retry_count = 0;
				flag = 0;
				for (i = 0; i < 4; i++)	{
					if (OLD_SIP[i] != Config_Msg.Lip[i]) {
						flag = 1;
						break;
					}
				}
				
				// change to new IP address
				if (flag) {
					iinchip_init();
					Set_network();
				}
				
				

				my_time = 0;
				next_time = my_time + DHCP_WAIT_TIME;

				dhcp_state = STATE_DHCP_LEASED;
			} else if (type == DHCP_NAK) {
				my_time = 0;
				next_time = my_time + DHCP_WAIT_TIME;
				retry_count = 0;
				dhcp_state = STATE_DHCP_DISCOVER;
				MyPrintf("state : STATE_DHCP_DISCOVER\r\n");
			} else check_Timeout();
		break;

		case STATE_DHCP_RELEASE :
		break;

		default :
		break;
	}
}

/*
*********************************************************************************************************
*              CHECK TIMEOUT
*
* Description: This function checks the timeout of DHCP in each state.
* Arguments  : None.
* Returns    : None.
* Note       : 
*********************************************************************************************************
*/
void check_Timeout(void)
{
	u8 i, d_addr[4];
	
	if (retry_count < MAX_DHCP_RETRY) {
		if (next_time < my_time) {
			my_time = 0;
			next_time = my_time + DHCP_WAIT_TIME;
			retry_count++;
			switch ( dhcp_state ) {
				case STATE_DHCP_DISCOVER :
					//MyPrintf("<<timeout>> state : STATE_DHCP_DISCOVER\r\n");
					send_DHCP_DISCOVER(SOCK_DHCP);
				break;
		
				case STATE_DHCP_REQUEST :
//					MyPrintf("<<timeout>> state : STATE_DHCP_REQUEST\r\n");

					for (i = 0; i < 4; i++) d_addr[i] = 0xff;
					send_DHCP_REQUEST(SOCK_DHCP, Cip, d_addr);
				break;

				case STATE_DHCP_REREQUEST :
//					MyPrintf("<<timeout>> state : STATE_DHCP_REREQUEST\r\n");
					
					for (i = 0; i < 4; i++)	d_addr[i] = DHCP_SIP[i];
					send_DHCP_REQUEST(SOCK_DHCP, Config_Msg.Lip, d_addr);
					
				break;
		
				default :
				break;
			}
		}
	} else {
		my_time = 0;
		next_time = my_time + DHCP_WAIT_TIME;
		retry_count = 0;

		DHCP_timeout = 1;

		/* open a socket in IP RAW mode for DHCP */
		socket(SOCK_DHCP, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
		send_DHCP_DISCOVER(SOCK_DHCP);
		dhcp_state = STATE_DHCP_DISCOVER;
	}
}


// check if a leased IP is valid
char check_leasedIP(void)
{
	u8 tmp;

	iinchip_init();
	//delay 100
	delay(10);
	
	Set_network();
	setRCR(1);

	tmp = socket(SOCK_DHCP, Sn_MR_UDP, REMOTE_CLIENT_PORT, 0x00);
	// Create UDP socket for network configuration
	tmp = socket(SOCK_CONFIG, Sn_MR_UDP, REMOTE_CLIENT_PORT, 0x00);
	
//	MyPrintf("\r\ncheck leased IP ");
	
	if (sendto(SOCK_DHCP, "CHECK_IP_CONFLICT", 17, Config_Msg.Lip, 5000) > 0)
	{
		send_DHCP_DECLINE(SOCK_DHCP);
		return 0;
	}
	return 1;
}	

/*
*********************************************************************************************************
*              Get an IP from the DHCP server.
*
* Description: 
* Arguments  : None.
* Returns    : None.
* Note       : 
*********************************************************************************************************
*/
unsigned char getIP_DHCPS(void)
{
	u8 ip[4];
	
	DHCP_XID = 0x12345678;

//	iinchip_init();
//      delay(100);	

	setSHAR(MAC);

	// SRC IP
	ip[0] = 0;
	ip[1] = 0;
	ip[2] = 0;
	ip[3] = 0;
	setSIPR(ip);

	setGAR(ip);
	setSUBR(ip);

	// SYS_INIT
	sysinit(0x06, 0x06);
//	sysinit(0x55, 0x55);
	
	delay(10);

	socket(SOCK_DHCP, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00);
	
	// Create UDP socket for network configuration
	socket(SOCK_CONFIG, Sn_MR_UDP, REMOTE_CLIENT_PORT, 0x00);

	send_DHCP_DISCOVER(SOCK_DHCP);
	
	dhcp_state = STATE_DHCP_DISCOVER;
	DHCP_timeout = 0;
	my_time = 0;
	next_time = my_time + DHCP_WAIT_TIME;
	retry_count = 0;

	while (dhcp_state != STATE_DHCP_LEASED)
	{

		if (Recv_ConfigMsg() == REMOTE_SETT) return(2);

		
		
		if (DHCP_timeout == 1) return(0);
		check_DHCP_state();
		
	}
	
	return 1;
}

⌨️ 快捷键说明

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