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

📄 dhcpc.c

📁 在freescale 的ne64上开发的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		*buf_ptr++=(UINT8)(localmachine.localip>>8);
		*buf_ptr++=(UINT8)(localmachine.localip);
	}else{
		buf_ptr+=4;	/* skip 4 bytes, buffer zeroed already */
	}

	/* yiaddr, siaddr, giaddr, skip */
	buf_ptr+=12;

	/* chaddr */
	*buf_ptr++=localmachine.localHW[5];
	*buf_ptr++=localmachine.localHW[4];
	*buf_ptr++=localmachine.localHW[3];
	*buf_ptr++=localmachine.localHW[2];
	*buf_ptr++=localmachine.localHW[1];
	*buf_ptr++=localmachine.localHW[0];
	buf_ptr+=10;

	/* sname and file, skip */
	buf_ptr+=192;

	/* options field. First magic cookie */
	*buf_ptr++=99;
	*buf_ptr++=130;
	*buf_ptr++=83;
	*buf_ptr++=99;

	/* message type */
	*buf_ptr++=DHCP_OPT_MSG_TYPE;
	*buf_ptr++=1;
	*buf_ptr++=msg_type;

	/* next depends on what state we're in and message type */
	switch(msg_type){

		case DHCP_REQUEST:
		case DHCP_DECLINE: /* sent only from REQUESTING state */

			/* Requested IP address MUST NOT be sent in RENEWING and
			 * REBINDING states (RFC2123 page 31)
			 */
			if((dhcpc_state!=DHCP_STATE_RENEWING)
				&&(dhcpc_state!=DHCP_STATE_REBINDING)){
				*buf_ptr++=DHCP_OPT_REQUESTED_IP;
				*buf_ptr++=4;
				*buf_ptr++=(UINT8)(dhcpc_requested_ip>>24);
				*buf_ptr++=(UINT8)(dhcpc_requested_ip>>16);
				*buf_ptr++=(UINT8)(dhcpc_requested_ip>>8);
				*buf_ptr++=(UINT8)(dhcpc_requested_ip);
			}
			/* server identifier, only when not in INIT_REBOOT state
			 *(RFC2131, Section 4.3.2) or RENEWING, REBINDING
			 * state (RFC2131 page 31)
			 */
			if((dhcpc_state!=DHCP_STATE_INIT_REBOOT)
				&&(dhcpc_state!=DHCP_STATE_REBOOTING)	/* for retransmissions */
				&&(dhcpc_state!=DHCP_STATE_RENEWING)
				&&(dhcpc_state!=DHCP_STATE_REBINDING)){
				*buf_ptr++=DHCP_OPT_SERV_IDENT;
				*buf_ptr++=4;
				*buf_ptr++=(UINT8)(dhcpc_server_identifier>>24);
				*buf_ptr++=(UINT8)(dhcpc_server_identifier>>16);
				*buf_ptr++=(UINT8)(dhcpc_server_identifier>>8);
				*buf_ptr++=(UINT8)(dhcpc_server_identifier);
			}
			/* go through to request parameters we're interested in, but
			 * only if we're not sending DECLINE message (parameter list
			 * MUST NOT be sent in such a message)
			 */
			 if(msg_type==DHCP_DECLINE)
			 	break;

		case DHCP_DISCOVER:
			/* parameter request list. These also MUST be transmitted
			 * with DHCP REQUEST message */
			*buf_ptr++=DHCP_OPT_PARAM_REQUEST;
			*buf_ptr++=7;	/* number of parameters we're requesting */
			*buf_ptr++=DHCP_OPT_SUBNET_MASK;
			*buf_ptr++=DHCP_OPT_ROUTER;
			*buf_ptr++=DHCP_OPT_DNS_SERVER;
			*buf_ptr++=DHCP_OPT_HOST_NAME;
			*buf_ptr++=DHCP_OPT_LEASE_TIME;
			*buf_ptr++=DHCP_OPT_T1_VALUE;
			*buf_ptr++=DHCP_OPT_T2_VALUE;
			break;

		default:
			break;
	}

	/* end option */
	*buf_ptr++=DHCP_OPT_END;
	while(buf_ptr<(net_buf+UDP_APP_OFFSET+300))
		*buf_ptr++=0x00;

	/* send message. Send unicast when server's IP is available (only
	 * in selected states, check RFC) and allowed (also check RFCs).
	 * Check RFCs in any case :-)
	 */
	if((dhcpc_state==DHCP_STATE_BOUND)
		||(dhcpc_state==DHCP_STATE_RENEWING))
		return (INT8)udp_send(dhcpc_soc_handle,dhcpc_server_identifier,DHCP_SERVER_PORT,net_buf+UDP_APP_OFFSET,NETWORK_TX_BUFFER_SIZE-UDP_APP_OFFSET,buf_ptr-(net_buf+UDP_APP_OFFSET));
	else
		return (INT8)udp_send(dhcpc_soc_handle,IP_BROADCAST_ADDRESS,DHCP_SERVER_PORT,net_buf+UDP_APP_OFFSET,NETWORK_TX_BUFFER_SIZE-UDP_APP_OFFSET,buf_ptr-(net_buf+UDP_APP_OFFSET));

}

/** \brief Processes received parameter from DHCP server
 * 	\author
 *		\li Vladan Jovanovic (vladan.jovanovic@violasystems.com)
 *	\date 23.05.2003
 *	\param n Number of bytes to read&process.
 *	\return Returns last for 4 bytes that were read as a 32-bit variable
 *
 *	This is internal function that get's invoked to read a received
 *	parameter in DHCP message. Introduced to optimize code a little
 *	as 4 byte parameters are often returned by DHCP server (netmask,
 *	gateway, server identifier, T1, T2, lease expiration time, DNS IP,..)
 */
UINT32 dhcpc_read_n_bytes(UINT8 n){
	UINT32 ret_value=0;
	/* read n bytes and return value of last of them (max 4, can be less)*/
	while(n--){
		ret_value=(ret_value<<8)|RECEIVE_NETWORK_B();
	}
	return ret_value;
}

/** \brief DHCP event listener, parses all DHCP replies
 * 	\author
 *		\li Vladan Jovanovic (vladan.jovanovic@violasystems.com)
 *	\date 23.05.2003
 *
 *	This is internal function invoked by OpenTCP UDP module when
 *	DHCP reply on a given UDP port is received. This function parses
 *	the response, checks for correctnes and performs certain actions
 *	based on the current state of DHCP client.
 */
INT32 dhcpc_eventlistener(INT8 cbhandle, UINT8 event, UINT32 ipaddr, UINT16 port, UINT16 buffindex, UINT16 datalen)
{
	UINT32 temp;
	UINT32 yiaddr;	/* assigned IP */
	UINT8 i;
	UINT8 msg_type=0;
	buffindex =0;
	port =0;
	if(cbhandle!=dhcpc_soc_handle){
		DEBUGOUT("DHCP Client: Not my handle!!!!\r\n");
		return (-1);
	}

	switch(event){
		case UDP_EVENT_DATA:
			DEBUGOUT("DHCP Client: Received data....");
			/* initial correctness checking */
			if(datalen<236){
				DEBUGOUT("length not OK, dumping packet\r\n");
				return (-1);
				}

			/* op */
			if(RECEIVE_NETWORK_B()!=BOOT_REPLY){
				DEBUGOUT("op not BOOT_REPLY, dumping packet\r\n");
				return (-1);
				}

			/* skip htype, hlen, hops */
			(void)RECEIVE_NETWORK_B();
			(void)RECEIVE_NETWORK_B();
			(void)RECEIVE_NETWORK_B();

			/* check xid */
			temp=0;
			temp|=((UINT32)RECEIVE_NETWORK_B())<<24;
			temp|=((UINT32)RECEIVE_NETWORK_B())<<16;
			temp|=((UINT32)RECEIVE_NETWORK_B())<<8;
			temp|=RECEIVE_NETWORK_B();
			if(temp!=0xAABBCCDD){
				DEBUGOUT("xid not OK, dumping packet\r\n");
				return (-1);
				}

			/* skip secs, flags, ciaddr and find yiaddr*/
			for(i=0;i<12;i++)
				yiaddr=(yiaddr<<8)|RECEIVE_NETWORK_B();

			 /* skip siaddr, giaddr, chaddr, sname, file.
			  * We get all the info we need from options.
			  */
			for(i=0;i<216;i++)
				RECEIVE_NETWORK_B();

			/* check magic cookie */
			temp=0;
			temp|=((UINT32)RECEIVE_NETWORK_B())<<24;
			temp|=((UINT32)RECEIVE_NETWORK_B())<<16;
			temp|=((UINT32)RECEIVE_NETWORK_B())<<8;
			temp|=RECEIVE_NETWORK_B();
			if(temp!=0x63825363){
				DEBUGOUT("magic cookie not OK, dumping packet\r\n");
				return (-1);
				}
			DEBUGOUT("initial check OK, proceeding...\r\n");
			/* process further received message, depends on state we're in */
			switch(dhcpc_state){
				case DHCP_STATE_SELECTING:
					/* select first DHCPOFFER */
					dhcpc_server_identifier=0;
					DEBUGOUT("DHCP Client state=SELECTING; ");
					/* iterate through parameters and try to find if
					 * this really is DHCPOFFER. Besides that, we're
					 * only interested in SERVERIDENTIFIER option (which
					 * is actually server's IP address)
					 */
					while((i=RECEIVE_NETWORK_B())!=DHCP_OPT_END){
						/* there are still options to process*/
						switch(i){
							case DHCP_OPT_MSG_TYPE:
								RECEIVE_NETWORK_B();
								msg_type=RECEIVE_NETWORK_B();
								break;
							case DHCP_OPT_SERV_IDENT:
								RECEIVE_NETWORK_B();
								/* Read SERVER IDENTIFIER */
								dhcpc_server_identifier|=((UINT32)RECEIVE_NETWORK_B())<<24;
								dhcpc_server_identifier|=((UINT32)RECEIVE_NETWORK_B())<<16;
								dhcpc_server_identifier|=((UINT32)RECEIVE_NETWORK_B())<<8;
								dhcpc_server_identifier|=RECEIVE_NETWORK_B();
								break;
							case DHCP_OPT_OVERLOAD:
								/* we can't process overloaded messages */
								DEBUGOUT("Overloaded DHCP message, can't process...\r\n");
								return (-1);
								break;
							default:
								/* not interesting parameter for now */
								if(i==DHCP_OPT_PAD)
									break;
								i=RECEIVE_NETWORK_B();	/* parameter length */
								while(i--){
									(void)RECEIVE_NETWORK_B();
								}
								break;
						}
					}
					/* ok, processed all, got what we were looking for ? */
					if((!dhcpc_server_identifier)||(msg_type!=DHCP_OFFER)){
						DEBUGOUT(" Not a DHCP offer or no server identifier; Aborting...\r\n");
						return(-1);
					}

					DEBUGOUT(" DHCP offer valid, sending DHCP REQUEST; State SELECTING-->REQUESTING\r\n");
					/* we have the offer, contact the server! */
					dhcpc_state=DHCP_STATE_REQUESTING;
					dhcpc_requested_ip=yiaddr;	/* offered IP ! */

					(void)dhcpc_send_message(DHCP_REQUEST);

					dhcpc_t1=4;	/* 4 secs for first retransmission */
					dhcpc_t2=8;	/* next one after 8 secs */
					break;

				case DHCP_STATE_REQUESTING:
					/* wait for DHCPACK */

					DEBUGOUT("DHCP Client state=REQUESTING; ");

					/* is message from the same server who sent the offer
					 * and assigned IP == offered IP? This will also reject
					 * subsequent DHCPOFFERs from slow DHCP servers.
					 */
					if((dhcpc_server_identifier!=ipaddr)||(yiaddr!=dhcpc_requested_ip)){
						DEBUGOUT("Server or requested IP not the same, dumping..\r\n");
						return (-1);
					}

					/* ok, go through param list and process them. We expect to get
					 * all the params here and that this is DHCPACK message
					 */
					DEBUGOUT("Received params: ");
					while((i=RECEIVE_NETWORK_B())!=DHCP_OPT_END){

						switch(i){
							case DHCP_OPT_PAD:
								break;
							case DHCP_OPT_SUBNET_MASK:
								temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								/* temp holds subnet mask, for now just show it and set params*/
								localmachine.netmask=temp;
								DEBUGOUT("Subnet mask;");
								break;
							case DHCP_OPT_ROUTER:
								temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								/* temp holds gateway IP */
								localmachine.defgw=temp;
								DEBUGOUT("Gateway IP; ");
								break;
							case DHCP_OPT_DNS_SERVER:
								temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								DEBUGOUT("DNS IP;");
								break;
							case DHCP_OPT_HOST_NAME:
								/* Read host name here and store it */
								i=RECEIVE_NETWORK_B();	/* length of host name */
								while(i--){
									/* read host name. Store this if necessary */
									(void)RECEIVE_NETWORK_B();
								}
								DEBUGOUT("Host name; ");
								break;
							case DHCP_OPT_LEASE_TIME:
								temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								/* time calculation from RFC! These values can also
								 * be received directly in options
								 */
								dhcpc_t1=(UINT32)((UINT16)(0.5)*temp);
								dhcpc_t2=(UINT32)((UINT16)(0.875)*temp);
								DEBUGOUT("Lease time;");
								break;
							case DHCP_OPT_OVERLOAD:
								DEBUGOUT("Overloaded DHCP message, can't process...\r\n");
								return (-1);
								break;
							case DHCP_OPT_MSG_TYPE:
								/* if this is DHCPACK we can switch state and assume
								 * that the parameters are OK
								 */
								RECEIVE_NETWORK_B();
								if(RECEIVE_NETWORK_B()==DHCP_ACK){
									DEBUGOUT("DHCP_ACK Message!; State REQUESTING-->BOUND; ");
									dhcpc_state=DHCP_STATE_BOUND;

									/* we should actually probe the received IP with
									 * ARP first, but let's wait with that for
									 * now.....
									 */
									localmachine.localip=dhcpc_requested_ip;
									/* dhcpc_requested_ip holds the assigned IP
									 * address. USE IT OR LOOSE IT!
									 */
									DEBUGOUT("IP address;");
								}else{
									DEBUGOUT("NOT DHCPACK message; dumping...\r\n");
									return(-1);
								}
								break;
							case DHCP_OPT_T1_VALUE:
								DEBUGOUT("T1;");
								dhcpc_t1=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								break;
							case DHCP_OPT_T2_VALUE:
								DEBUGOUT("T2; ");
								dhcpc_t2=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								break;
							default:
								dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								break;
						}
					}
					DEBUGOUT("\r\n");
					break;
				case DHCP_STATE_RENEWING:
				case DHCP_STATE_REBINDING:
				case DHCP_STATE_REBOOTING:
					/* wait for DHCPACK. If we get DHCPNAK restart. Here
					 * we're only interested in ACK and T1 and T2 parameters.
					 * NOTE: other parameters can change as well during time(
					 * DNS, gateway etc. Add cases similar to those in
					 * REQUESTING state here as well if you want those.
					 */
					DEBUGOUT("DHCP Client state=REQUESTING or REBINDING; ");
					while((i=RECEIVE_NETWORK_B())!=DHCP_OPT_END){
						switch(i){
							case DHCP_OPT_PAD:
								break;
							case DHCP_OPT_LEASE_TIME:
								DEBUGOUT("Lease time; ");
								temp=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								/* time calculation from RFC! These values can also
								 * be received directly in options
								 */
								dhcpc_t1=(UINT32)((UINT16)(0.5)*temp);
								dhcpc_t2=(UINT32)((UINT16)(0.875)*temp);
								break;
							case DHCP_OPT_MSG_TYPE:
								RECEIVE_NETWORK_B();
								i=RECEIVE_NETWORK_B();
								if(i==DHCP_NAK){
									DEBUGOUT("DHCP_NAK received; State --> INIT\r\n");
									dhcpc_state=DHCP_STATE_INIT;
									localmachine.localip=0;
									return(-1);
								}
								if(i==DHCP_ACK){
									DEBUGOUT("DHCP_ACK received; State --> BOUND\r\n");
									dhcpc_state=DHCP_STATE_BOUND;
								}
								break;
							case DHCP_OPT_T1_VALUE:
								DEBUGOUT("T1; ");
								dhcpc_t1=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								break;
							case DHCP_OPT_T2_VALUE:
								DEBUGOUT("T2; ");
								dhcpc_t2=dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								break;
							default:
								dhcpc_read_n_bytes(RECEIVE_NETWORK_B());
								break;
						}
					}
					break;
				default:
					/* dump frames when in all other states */
					break;
			}
			break;
		default:
			/* should never get here */
			DEBUGOUT("DHCP Client: Unknown UDP event :-( \r\n");
			break;
	}
	return 1;

}

#endif

⌨️ 快捷键说明

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