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

📄 bootp.c

📁 opentcp_mcf5282原代码
💻 C
字号:
/***************************************************************************************
File:			bootp.c

Date:			7.10.2002

Version:		0.1

Author:			Jari Lahti (jari@violasystems.com)

Description:	This file implements BOOT protocol client

Version Info:	7.10.2002 - First version (Jari Lahti)

***************************************************************************************/

#include "opentcp.h"


UINT8 bootpapp_init = 0;

struct
{
	UINT8 	state;
	UINT8 	mode;
	INT8	sochandle;
	UINT16	tmrhandle;
	UINT16	bootsecs;

} Bootp;



/********************************************************************************
Function:		init_bootpc

Parameters:		UINT8 mode - 0: Do not save parameters permanently
							 1: Save parameters permanently

Return val:		INT8 - 	(>=0) OK
						(-1) Error

Date:			7.19.2002

Desc:			This function should be called before the BOOTP application
				is used to set the operating parameters of it
*********************************************************************************/

INT8 init_bootpc (UINT8 mode)
{
	/* Already initialized?	*/

	if(bootpapp_init)
		return(1);

	/* Get socket handle		*/

	Bootp.sochandle = udp_getsocket(0, bootpc_eventlistener, UDP_OPT_SEND_CS | UDP_OPT_CHECK_CS);

	if(Bootp.sochandle < 0)
		return(-1);

	/* Put it to listening mode	*/

	if( udp_open(Bootp.sochandle, BOOTP_CLIENTPORT) < 0 )
		return(-1);

	/* Get timer handle			*/

	Bootp.tmrhandle = get_timer();
	Bootp.bootsecs = 0;
	Bootp.mode = mode;

	Bootp.state = BOOTPC_STATE_DISABLED;

	bootpapp_init = 1;

	return(1);

}

/********************************************************************************
Function:		bootpc_stop

Parameters:		void

Return val:		void

Date:			9.10.2002

Desc:			Closes the bootp
*********************************************************************************/

void bootpc_stop (void)
{
	if(bootpapp_init == 0)
		return;

	Bootp.state = BOOTPC_STATE_DISABLED;
}

/********************************************************************************
Function:		bootpc_enable

Parameters:		void

Return val:		INT8 (-1) - Error
					 (>=0) - OK

Date:			9.10.2002

Desc:			Enables the bootp
*********************************************************************************/

INT8 bootpc_enable (void)
{
	if(bootpapp_init == 0)
		return(-1);

	Bootp.state = BOOTPC_STATE_ENABLED;

	return(1);

}

/********************************************************************************
Function:		bootpc_run

Parameters:		void

Return val:		void

Date:			7.10.2002

Desc:			The main thread of bootp that should be called periodically
*********************************************************************************/

void bootpc_run (void)
{
	INT16 i;

	/* State machine	*/

	if(bootpapp_init == 0)
		return;

	switch(Bootp.state)
	{
		case BOOTPC_STATE_ENABLED:

			/* Check the IP address of the device and start BOOTP procedure for getting	*/
			/* one if zero or 255.255.255.255											*/

			if( (localmachine.localip == 0) || (localmachine.localip == 0xFFFFFFFF) )
			{
				/* We need to start BOOTP request procedure	*/
				/* Firstly wait random time					*/

				localmachine.localip = 0;
				localmachine.defgw = 0;
				localmachine.netmask = 0;

				init_timer(Bootp.tmrhandle, ((UINT32)(localmachine.localHW[0]) << 2) + localmachine.localHW[1]);
				Bootp.state = BOOTPC_STATE_REQUEST_NEEDED;
			}

			return;

		case BOOTPC_STATE_REQUEST_NEEDED:

			if( check_timer(Bootp.tmrhandle) != 0 )
				return;

			/* Send request if we haven't get the IP in some other way	*/

			if(localmachine.localip != 0)
			{
				Bootp.state = BOOTPC_STATE_ENABLED;
				return;

			}


			i = 0;

			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x01;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x01;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x06;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0xCA;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x03;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x32;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0xF1;

			OTCP_TXBUF[UDP_APP_OFFSET + i++] = (UINT8)(Bootp.bootsecs >> 8);
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = (UINT8)Bootp.bootsecs;

			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x80;

			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 0x00;

			OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[5];
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[4];
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[3];
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[2];
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[1];
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = localmachine.localHW[0];

			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 99;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 130;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 83;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 99;
			OTCP_TXBUF[UDP_APP_OFFSET + i++] = 255;

			for(i;i<300;i++)
				OTCP_TXBUF[UDP_APP_OFFSET + i] = 0;

			/* Send it	*/

			udp_send(Bootp.sochandle, IP_BROADCAST_ADDRESS, BOOTP_SERVERPORT, &OTCP_TXBUF[UDP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - UDP_APP_OFFSET, 300);

			init_timer(Bootp.tmrhandle, BOOTP_RETRY_TOUT*TIMERTIC);

			Bootp.bootsecs += BOOTP_RETRY_TOUT*TIMERTIC;

			Bootp.state = BOOTPC_STATE_WAITING_REPLY;

			return;

		case BOOTPC_STATE_WAITING_REPLY:

			/* Wait untill timeout elapsed and try again	*/

			if( check_timer(Bootp.tmrhandle) != 0 )
				return;

			/* Try again									*/

			Bootp.state = BOOTPC_STATE_REQUEST_NEEDED;

			return;

		case BOOTPC_STATE_REPLY_GET:


			/* You can save the parameters here to e.g. EEPROM	*/

			Bootp.state = BOOTPC_STATE_ENABLED;

			return;


		default:

			return;
	}

}

INT32 bootpc_eventlistener (INT8 cbhandle, UINT8 event, UINT32 remip, UINT16 remport, UINT16 bufindex, UINT16 dlen)
{
	INT16 i,j;
	UINT32 ip = 0;
	UINT32 nm = 0;
	UINT32 dgw = 0;
	UINT8 ch;


	/* This function is called by UDP stack to inform about events	*/

	if(bootpapp_init == 0)
		return(-1);

	if( cbhandle != Bootp.sochandle)		/* Not our handle	*/
		return(-1);

	/* The only event is data	*/

	if(Bootp.state != BOOTPC_STATE_WAITING_REPLY)
		return(-1);

	/* Process reply	*/

	NETWORK_RECEIVE_INITIALIZE(bufindex);

	if(dlen < 300)
		return(-1);

	if(	RECEIVE_NETWORK_B() != BOOTP_REPLY)
		return(-1);

	if(	RECEIVE_NETWORK_B() != BOOTP_HTYPE_ETHERNET)
		return(-1);

	if(	RECEIVE_NETWORK_B() != BOOTP_HWLEN_ETHERNET)
		return(-1);

	RECEIVE_NETWORK_B();		/* Skip hops	*/

	/* Check transaction ID	*/

	if(	RECEIVE_NETWORK_B() != 0xCA)
		return(-1);

	if(	RECEIVE_NETWORK_B() != 0x03)
		return(-1);

	if(	RECEIVE_NETWORK_B() != 0x32)
		return(-1);

	if(	RECEIVE_NETWORK_B() != 0xF1)
		return(-1);

	/* Skip elapsed, unused, client address	*/

	for(i=0; i<8; i++)
		RECEIVE_NETWORK_B();

	/* Get IP	*/

	ip = RECEIVE_NETWORK_B();
	ip <<= 8;
	ip |= RECEIVE_NETWORK_B();
	ip <<= 8;
	ip |= RECEIVE_NETWORK_B();
	ip <<= 8;
	ip |= RECEIVE_NETWORK_B();

	/* Skip server ip & bootp router address	*/

	for(i=0; i<8; i++)
		RECEIVE_NETWORK_B();

	/* Check MAC								*/

	if(	RECEIVE_NETWORK_B() != localmachine.localHW[0])
		return(-1);

	if(	RECEIVE_NETWORK_B() != localmachine.localHW[1])
		return(-1);

	if(	RECEIVE_NETWORK_B() != localmachine.localHW[2])
		return(-1);

	if(	RECEIVE_NETWORK_B() != localmachine.localHW[3])
		return(-1);

	if(	RECEIVE_NETWORK_B() != localmachine.localHW[4])
		return(-1);

	if(	RECEIVE_NETWORK_B() != localmachine.localHW[5])
		return(-1);

	RECEIVE_NETWORK_B();
	RECEIVE_NETWORK_B();

	for(i=0; i<200; i++)
		RECEIVE_NETWORK_B();

	/* Check options	*/

	dlen -= 236;

	i = 0;

	while(i<dlen)
	{
		ch = RECEIVE_NETWORK_B();
		i++;

		if( (ch != BOOTP_OPTION_SUBNETMASK) && (ch != BOOTP_OPTION_DEFGW) )
		{
			/* Not supported option, skip it	*/

			j = RECEIVE_NETWORK_B();
			i++;

			if(j >= 2)
			{
				j -= 2;

				while(j--)
				{
					RECEIVE_NETWORK_B();
					i++;
				}
			}

			continue;

		}

		if( ch == BOOTP_OPTION_SUBNETMASK)
		{
			RECEIVE_NETWORK_B();			/* Skip totlen	*/
			nm = RECEIVE_NETWORK_B();
			nm <<= 8;
			nm |= RECEIVE_NETWORK_B();
			nm <<= 8;
			nm |= RECEIVE_NETWORK_B();
			nm <<= 8;
			nm |= RECEIVE_NETWORK_B();

			i += 5;

		}

		if( ch == BOOTP_OPTION_DEFGW)
		{
			j = RECEIVE_NETWORK_B();		/* Get totlen	*/
			dgw = RECEIVE_NETWORK_B();
			dgw <<= 8;
			dgw |= RECEIVE_NETWORK_B();
			dgw <<= 8;
			dgw |= RECEIVE_NETWORK_B();
			dgw <<= 8;
			dgw |= RECEIVE_NETWORK_B();

			i += 5;

			/* Skip others	*/

			if( j>5 )
			{
				j -= 5;

				while(j--)
				{
					RECEIVE_NETWORK_B();
					i++;
				}

			}

		}

	}

	/* Store parameters		*/

	localmachine.localip = ip;
	localmachine.defgw = dgw;
	localmachine.netmask = nm;

	/* Change state	*/

	Bootp.state = BOOTPC_STATE_REPLY_GET;


	return(1);


}

⌨️ 快捷键说明

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