|
|
|
@ -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.
|
|
|
|
|
*/ |
|
|
|
|