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

📄 tftps.c

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

Date:			7.10.2002

Version:		0.1

Author:			Jari Lahti (jari@violasystems.com)

Description:	This file implements TFTP protocol server

Version Info:	7.10.2002 - First version (Jari Lahti)

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

#include "opentcp.h"


UINT8 tftpsapp_init = 0;


/* TFTPS states			*/

#define TFTPS_STATE_ENABLED		1
#define TFTPS_STATE_CONNECTED	2



/* TFTP Error codes		*/

#define	TFTP_NOTDEFINED			0	/* Not Definet Error 		*/
#define	TFTP_ACCESSVIOLATION	2	/* Access Violation	Error	*/
#define	TFTP_ILLEGALOPERATION	4	/* Not supported Opcode		*/


/* TFTP Opcodes		*/

#define	TFTP_OPCODE_WRQ			2	/* Packet is Write Request	*/
#define	TFTP_OPCODE_DATA		3	/* Data Packet				*/
#define TFTP_OPCODE_ACK			4	/* ACK Packet				*/
#define TFTP_OPCODE_ERROR		5	/* Error Packet				*/

struct
{
	UINT8 	state;
	INT8	sochandle;
	UINT16	tmrhandle;
	UINT32 	remip;
	UINT16 	remport;
	UINT16	blocknumber;
	UINT32 	bytecount;
	UINT8 	retries;

} Tftps;




/********************************************************************************
Function:		init_tftps

Parameters:		void

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

Date:			7.19.2002

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

INT8 init_tftps (void)
{
	/* Already initialized?	*/

	if(tftpsapp_init)
		return(1);

	/* Get socket handle		*/

	Tftps.sochandle = udp_getsocket(0, tftps_eventlistener, UDP_OPT_SEND_CS | UDP_OPT_CHECK_CS);

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

	/* Put it to listening mode	*/

	if( udp_open(Tftps.sochandle, TFTPS_SERVERPORT) < 0 )
		return(-1);

	/* Get timer handle			*/

	Tftps.tmrhandle = get_timer();

	Tftps.state = TFTPS_STATE_ENABLED;
	Tftps.remip = 0;
	Tftps.remport = 0;
	Tftps.retries = 0;
	Tftps.blocknumber = 0;
	Tftps.bytecount = 0;

	tftpsapp_init = 1;

	return(1);

}

/********************************************************************************
Function:		tftps_run

Parameters:		void

Return val:		void

Date:			7.10.2002

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

void tftps_run (void)
{
	if(tftpsapp_init == 0)
		return;

	/* Check for timeouts	*/

	if(Tftps.state == TFTPS_STATE_CONNECTED)
	{
		if(check_timer(Tftps.tmrhandle) == 0)
			TFTP_DeleteSocket();
	}

}

INT32 tftps_eventlistener (INT8 cbhandle, UINT8 event, UINT32 remip, UINT16 remport, UINT16 bufindex, UINT16 dlen)
{
	UINT16 opcode;
	UINT16 i;
	UINT8 ch;
	UINT16 u16temp;
	UINT8 fname[TFTPS_FILENAME_MAXLEN];

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

	if(cbhandle != Tftps.sochandle)
		return(-1);

	/* If we are on other state than enabled, check that we are talking with the same gyu	*/

	if(	Tftps.state != TFTPS_STATE_ENABLED)
	{
		if(remip != Tftps.remip)
			return(-1);
		if(remport != Tftps.remport)
			return(-1);
	}

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

	/* Bind socket	*/

	Tftps.remip = remip;
	Tftps.remport = remport;

	/* Get information	*/

	NETWORK_RECEIVE_INITIALIZE(bufindex);

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

	dlen -= 2;

	/* Process it	*/

	switch(opcode)
	{
		case TFTP_OPCODE_WRQ:							/* Write request?	*/

			/* Get filename	*/

			fname[0] = '\0';

			for(i=0; i<dlen; i++)
			{
				if(i >= TFTPS_FILENAME_MAXLEN)
				{
					TFTP_SendError(TFTP_NOTDEFINED);
					TFTP_DeleteSocket();
					return(1);
				}

				ch = RECEIVE_NETWORK_B();

				fname[i] = ch;

				if(ch == '\0')
				{
					i++;
					break;
				}
			}

			dlen -= i;

			/* Check here the filename	*/

			if( otcp_bufsearch(&fname[0], TFTPS_FILENAME_MAXLEN, (UINT8*)"ws100.upn",0) < 0 )
			{

				TFTP_SendError(TFTP_ACCESSVIOLATION);
				TFTP_DeleteSocket();
				return(1);
			}

			/* Check mode, only octet mode is supported	*/

			if(dlen < 6)
			{
				TFTP_SendError(TFTP_NOTDEFINED);
				TFTP_DeleteSocket();
				return(1);
			}

			if( (RECEIVE_NETWORK_B() != 'o') || (RECEIVE_NETWORK_B() != 'c') || (RECEIVE_NETWORK_B() != 't') ||
				(RECEIVE_NETWORK_B() != 'e') || (RECEIVE_NETWORK_B() != 't') || (RECEIVE_NETWORK_B() != '\0')	)
			{
				TFTP_SendError(TFTP_NOTDEFINED);
				TFTP_DeleteSocket();
				return(1);
			}

			/* All OK, send ACK	*/

			Tftps.state = TFTPS_STATE_CONNECTED;
			Tftps.blocknumber = 0;
			Tftps.bytecount = 0;
			Tftps.retries = TFTPS_DEF_RETRIES;
			init_timer(Tftps.tmrhandle, TFTPS_TIMEOUT*TIMERTIC);

			TFTP_SendAck();

			Tftps.blocknumber++;

			return(1);


		case TFTP_OPCODE_DATA:											/* Data Packet ? */

			if(Tftps.state != TFTPS_STATE_CONNECTED)
			{
				TFTP_SendError(TFTP_NOTDEFINED);
				TFTP_DeleteSocket();
				return(1);
			}

			if(dlen < 2)
			{
				TFTP_SendError(TFTP_NOTDEFINED);
				TFTP_DeleteSocket();
				return(1);
			}

			/* Get block number	*/

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

			dlen -= 2;

			if( (u16temp < Tftps.blocknumber) && (Tftps.blocknumber > 0) )
			{
				/* Duplicate msg, send ACK again	*/

				if( Tftps.retries > 0 )
				{
					Tftps.retries--;
					Tftps.blocknumber--;
					TFTP_SendAck();
					Tftps.blocknumber++;
				}
				else
				{
					TFTP_SendError(TFTP_NOTDEFINED);
					TFTP_DeleteSocket();
				}

				return(1);
			}

			if( u16temp != Tftps.blocknumber )
			{
				/* Something really wrong */

				TFTP_SendError(TFTP_NOTDEFINED);
				TFTP_DeleteSocket();
				return(1);
			}

			/* Read the data here with RECEIVE_NETWORK_B()	*/



			if( dlen < 512 )
			{
				/* Other side Wants to close */

				TFTP_SendAck();
				TFTP_DeleteSocket();
				return(1);
			}

			/* All OK	*/

			Tftps.retries = TFTPS_DEF_RETRIES;
			init_timer(Tftps.tmrhandle, TFTPS_TIMEOUT*TIMERTIC);
			TFTP_SendAck();
			Tftps.blocknumber++;

			return(1);

		case TFTP_OPCODE_ERROR:

			TFTP_DeleteSocket();

			return(1);

		default:

			/* Unsupported Opcode, Send error */

			TFTP_SendError(TFTP_ILLEGALOPERATION);
			TFTP_DeleteSocket();

			return(1);
	}

}


void TFTP_SendAck (void)
{
	/* Send a TFTP ACK packet */

	OTCP_TXBUF[UDP_APP_OFFSET + 0] = 0;		/* Opcode	*/
	OTCP_TXBUF[UDP_APP_OFFSET + 1] = 4;
	OTCP_TXBUF[UDP_APP_OFFSET + 2] = (UINT8)(Tftps.blocknumber >> 8);
	OTCP_TXBUF[UDP_APP_OFFSET + 3] = (UINT8)Tftps.blocknumber;

	udp_send(Tftps.sochandle, Tftps.remip, Tftps.remport, &OTCP_TXBUF[UDP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - UDP_APP_OFFSET, 4);


}




void TFTP_SendError (UINT8 errno )
{
	/* Send TFTP Error -packet */

	OTCP_TXBUF[UDP_APP_OFFSET + 0] = 0;		/* Opcode	*/
	OTCP_TXBUF[UDP_APP_OFFSET + 1] = 5;
	OTCP_TXBUF[UDP_APP_OFFSET + 2] = (UINT8)(Tftps.blocknumber >> 8);
	OTCP_TXBUF[UDP_APP_OFFSET + 3] = (UINT8)Tftps.blocknumber;
	OTCP_TXBUF[UDP_APP_OFFSET + 4] = errno;
	OTCP_TXBUF[UDP_APP_OFFSET + 5] = '\0';
	OTCP_TXBUF[UDP_APP_OFFSET + 6] = 0;

	udp_send(Tftps.sochandle, Tftps.remip, Tftps.remport, &OTCP_TXBUF[UDP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - UDP_APP_OFFSET, 7);

}

void TFTP_DeleteSocket (void)
{
	/* Clear Socket Data */

	Tftps.blocknumber = 0;
	Tftps.state = TFTPS_STATE_ENABLED;
	Tftps.retries = 0;
	Tftps.remip = 0;
	Tftps.remport = 0;


}



/* EOF	*/

⌨️ 快捷键说明

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