diff options
Diffstat (limited to 'net/tftp.c')
| -rw-r--r-- | net/tftp.c | 62 | 
1 files changed, 58 insertions, 4 deletions
| diff --git a/net/tftp.c b/net/tftp.c index 6386740b1..6d4429887 100644 --- a/net/tftp.c +++ b/net/tftp.c @@ -2,6 +2,8 @@   * Copyright 1994, 1995, 2000 Neil Russell.   * (See License)   * Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de + * Copyright 2011 Comelit Group SpA, + *                Luca Ceresoli <luca.ceresoli@comelit.it>   */  #include <common.h> @@ -85,6 +87,7 @@ static short	TftpNumchars;  #define STATE_TOO_LARGE	3  #define STATE_BAD_MAGIC	4  #define STATE_OACK	5 +#define STATE_RECV_WRQ	6  /* default TFTP block size */  #define TFTP_BLOCK_SIZE		512 @@ -257,6 +260,8 @@ TftpSend(void)  							    (Mapsize*8), 0);  		/*..falling..*/  #endif + +	case STATE_RECV_WRQ:  	case STATE_DATA:  		xp = pkt;  		s = (ushort *)pkt; @@ -309,7 +314,8 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,  #endif  			return;  	} -	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort) +	if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort && +	    TftpState != STATE_RECV_WRQ)  		return;  	if (len < 2) @@ -322,12 +328,24 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,  	switch (ntohs(proto)) {  	case TFTP_RRQ: -	case TFTP_WRQ:  	case TFTP_ACK:  		break;  	default:  		break; +#ifdef CONFIG_CMD_TFTPSRV +	case TFTP_WRQ: +		debug("Got WRQ\n"); +		TftpRemoteIP = sip; +		TftpRemotePort = src; +		TftpOurPort = 1024 + (get_timer(0) % 3072); +		TftpLastBlock = 0; +		TftpBlockWrap = 0; +		TftpBlockWrapOffset = 0; +		TftpSend(); /* Send ACK(0) */ +		break; +#endif +  	case TFTP_OACK:  		debug("Got OACK: %s %s\n",  			pkt, @@ -402,7 +420,8 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,  		if (TftpState == STATE_SEND_RRQ)  			debug("Server did not acknowledge timeout option!\n"); -		if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK) { +		if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK || +		    TftpState == STATE_RECV_WRQ) {  			/* first block received */  			TftpState = STATE_DATA;  			TftpRemotePort = src; @@ -537,7 +556,8 @@ TftpTimeout(void)  	} else {  		puts("T ");  		NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); -		TftpSend(); +		if (TftpState != STATE_RECV_WRQ) +			TftpSend();  	}  } @@ -661,6 +681,40 @@ TftpStart(void)  	TftpSend();  } +#ifdef CONFIG_CMD_TFTPSRV +void +TftpStartServer(void) +{ +	tftp_filename[0] = 0; + +#if defined(CONFIG_NET_MULTI) +	printf("Using %s device\n", eth_get_name()); +#endif +	printf("Listening for TFTP transfer on %pI4\n", &NetOurIP); +	printf("Load address: 0x%lx\n", load_addr); + +	puts("Loading: *\b"); + +	TftpTimeoutCountMax = TIMEOUT_COUNT; +	TftpTimeoutCount = 0; +	TftpTimeoutMSecs = TIMEOUT; +	NetSetTimeout(TftpTimeoutMSecs, TftpTimeout); + +	/* Revert TftpBlkSize to dflt */ +	TftpBlkSize = TFTP_BLOCK_SIZE; +	TftpBlock = 0; +	TftpOurPort = WELL_KNOWN_PORT; + +#ifdef CONFIG_TFTP_TSIZE +	TftpTsize = 0; +	TftpNumchars = 0; +#endif + +	TftpState = STATE_RECV_WRQ; +	NetSetHandler(TftpHandler); +} +#endif /* CONFIG_CMD_TFTPSRV */ +  #ifdef CONFIG_MCAST_TFTP  /* Credits: atftp project.   */ |