@ -39,21 +39,21 @@
# define TFTP_ERROR 5
# define TFTP_OACK 6
static ulong TftpTimeoutMSec s = TIMEOUT ;
static int TftpTimeoutCountM ax = TIMEOUT_COUNT ;
static ulong timeout_m s = TIMEOUT ;
static int timeout_count_m ax = TIMEOUT_COUNT ;
static ulong time_start ; /* Record time we started tftp */
/*
* These globals govern the timeout behavior when attempting a connection to a
* TFTP server . TftpRRQTimeoutMSec s specifies the number of milliseconds to
* TFTP server . tftp_timeout_m s specifies the number of milliseconds to
* wait for the server to respond to initial connection . Second global ,
* TftpRRQTimeoutCountM ax, gives the number of such connection retries .
* TftpRRQTimeoutCountM ax must be non - negative and TftpRRQTimeoutMSec s must be
* tftp_timeout_count_m ax, gives the number of such connection retries .
* tftp_timeout_count_m ax must be non - negative and tftp_timeout_m s must be
* positive . The globals are meant to be set ( and restored ) by code needing
* non - standard timeout behavior when initiating a TFTP transfer .
*/
ulong TftpRRQTimeoutMSec s = TIMEOUT ;
int TftpRRQTimeoutCountM ax = TIMEOUT_COUNT ;
ulong tftp_timeout_m s = TIMEOUT ;
int tftp_timeout_count_m ax = TIMEOUT_COUNT ;
enum {
TFTP_ERR_UNDEFINED = 0 ,
@ -67,30 +67,32 @@ enum {
static struct in_addr tftp_remote_ip ;
/* The UDP port at their end */
static int TftpRemoteP ort;
static int tftp_remote_p ort;
/* The UDP port at our end */
static int TftpOurP ort;
static int TftpTimeoutC ount;
static int tftp_our_p ort;
static int timeout_c ount;
/* packet sequence number */
static ulong TftpB lock;
static ulong tftp_cur_b lock;
/* last packet sequence number received */
static ulong TftpLastB lock;
static ulong tftp_prev_b lock;
/* count of sequence number wraparounds */
static ulong TftpBlockW rap;
static ulong tftp_block_w rap;
/* memory offset due to wrapping */
static ulong TftpBlockWrapO ffset;
static int TftpS tate;
static ulong tftp_block_wrap_o ffset;
static int tftp_s tate;
# ifdef CONFIG_TFTP_TSIZE
/* The file size reported by the server */
static int TftpT size;
static int tftp_t size;
/* The number of hashes we printed */
static short TftpNumchars ;
static short tftp_tsize_num_hash ;
# endif
# ifdef CONFIG_CMD_TFTPPUT
static int TftpWriting ; /* 1 if writing, else 0 */
static int TftpFinalBlock ; /* 1 if we have sent the last block */
/* 1 if writing, else 0 */
static int tftp_put_active ;
/* 1 if we have sent the last block */
static int tftp_put_final_block_sent ;
# else
# define TftpWriting 0
# define tftp_put_active 0
# endif
# define STATE_SEND_RRQ 1
@ -128,41 +130,42 @@ static char tftp_filename[MAX_LEN];
# define TFTP_MTU_BLOCKSIZE 1468
# endif
static unsigned short TftpBlkS ize = TFTP_BLOCK_SIZE ;
static unsigned short TftpBlkSizeO ption = TFTP_MTU_BLOCKSIZE ;
static unsigned short tftp_block_s ize = TFTP_BLOCK_SIZE ;
static unsigned short tftp_block_size_o ption = TFTP_MTU_BLOCKSIZE ;
# ifdef CONFIG_MCAST_TFTP
# include <malloc.h>
# define MTFTP_BITMAPSIZE 0x1000
static unsigned * Bitmap ;
static int PrevBitmapHole , Mapsize = MTFTP_BITMAPSIZE ;
static uchar ProhibitMcast , MasterClient ;
static uchar Multicast ;
static int Mcast_port ;
static ulong TftpEndingBlock ; /* can get 'last' block before done..*/
static unsigned * tftp_mcast_bitmap ;
static int tftp_mcast_prev_hole ;
static int tftp_mcast_bitmap_size = MTFTP_BITMAPSIZE ;
static int tftp_mcast_disabled ;
static int tftp_mcast_master_client ;
static int tftp_mcast_active ;
static int tftp_mcast_port ;
/* can get 'last' block before done..*/
static ulong tftp_mcast_ending_block ;
static void parse_multicast_oack ( char * pkt , int len ) ;
static void
mcast_cleanup ( void )
static void mcast_cleanup ( void )
{
if ( net_mcast_addr )
eth_mcast_join ( net_mcast_addr , 0 ) ;
if ( B itmap)
free ( B itmap) ;
B itmap = NULL ;
if ( tftp_mcast_b itmap)
free ( tftp_mcast_b itmap) ;
tftp_mcast_b itmap = NULL ;
net_mcast_addr . s_addr = 0 ;
Multicast = 0 ;
M cast_port = 0 ;
TftpEndingB lock = - 1 ;
tftp_mcast_active = 0 ;
tftp_m cast_port = 0 ;
tftp_mcast_ending_b lock = - 1 ;
}
# endif /* CONFIG_MCAST_TFTP */
static inline void
store_block ( int block , uchar * src , unsigned len )
static inline void store_block ( int block , uchar * src , unsigned len )
{
ulong offset = block * TftpBlkSize + TftpBlockWrapO ffset;
ulong offset = block * tftp_block_size + tftp_block_wrap_o ffset;
ulong newsize = offset + len ;
# ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
int i , rc = 0 ;
@ -193,8 +196,8 @@ store_block(int block, uchar *src, unsigned len)
unmap_sysmem ( ptr ) ;
}
# ifdef CONFIG_MCAST_TFTP
if ( Multicast )
ext2_set_bit ( block , B itmap) ;
if ( tftp_mcast_active )
ext2_set_bit ( block , tftp_mcast_b itmap) ;
# endif
if ( net_boot_file_size < newsize )
@ -204,11 +207,11 @@ store_block(int block, uchar *src, unsigned len)
/* Clear our state ready for a new transfer */
static void new_transfer ( void )
{
TftpLastB lock = 0 ;
TftpBlockW rap = 0 ;
TftpBlockWrapO ffset = 0 ;
tftp_prev_b lock = 0 ;
tftp_block_w rap = 0 ;
tftp_block_wrap_o ffset = 0 ;
# ifdef CONFIG_CMD_TFTPPUT
TftpFinalBlock = 0 ;
tftp_put_final_block_sent = 0 ;
# endif
}
@ -224,38 +227,39 @@ static void new_transfer(void)
static int load_block ( unsigned block , uchar * dst , unsigned len )
{
/* We may want to get the final block from the previous set */
ulong offset = ( ( int ) block - 1 ) * len + TftpBlockWrapO ffset;
ulong offset = ( ( int ) block - 1 ) * len + tftp_block_wrap_o ffset;
ulong tosend = len ;
tosend = min ( net_boot_file_size - offset , tosend ) ;
( void ) memcpy ( dst , ( void * ) ( save_addr + offset ) , tosend ) ;
debug ( " %s: block=%d, offset=%ld, len=%d, tosend=%ld \n " , __func__ ,
block , offset , len , tosend ) ;
block , offset , len , tosend ) ;
return tosend ;
}
# endif
static void TftpS end( void ) ;
static void TftpTimeout ( void ) ;
static void tftp_s end( void ) ;
static void tftp_timeout_handler ( void ) ;
/**********************************************************************/
static void show_block_marker ( void )
{
# ifdef CONFIG_TFTP_TSIZE
if ( TftpTsize ) {
ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset ;
if ( tftp_tsize ) {
ulong pos = tftp_cur_block * tftp_block_size +
tftp_block_wrap_offset ;
while ( TftpNumchars < pos * 50 / TftpT size) {
while ( tftp_tsize_num_hash < pos * 50 / tftp_t size) {
putc ( ' # ' ) ;
TftpNumchars + + ;
tftp_tsize_num_hash + + ;
}
} else
# endif
{
if ( ( ( TftpB lock - 1 ) % 10 ) = = 0 )
if ( ( ( tftp_cur_b lock - 1 ) % 10 ) = = 0 )
putc ( ' # ' ) ;
else if ( ( TftpB lock % ( 10 * HASHES_PER_LINE ) ) = = 0 )
else if ( ( tftp_cur_b lock % ( 10 * HASHES_PER_LINE ) ) = = 0 )
puts ( " \n \t " ) ;
}
}
@ -287,10 +291,10 @@ static void update_block_number(void)
* number of 0 this means that there was a wrap
* around of the ( 16 bit ) counter .
*/
if ( TftpB lock = = 0 & & TftpLastB lock ! = 0 ) {
TftpBlockW rap+ + ;
TftpBlockWrapOffset + = TftpBlkS ize * TFTP_SEQUENCE_SIZE ;
TftpTimeoutC ount = 0 ; /* we've done well, reset th he timeout */
if ( tftp_cur_b lock = = 0 & & tftp_prev_b lock ! = 0 ) {
tftp_block_w rap+ + ;
tftp_block_wrap_offset + = tftp_block_s ize * TFTP_SEQUENCE_SIZE ;
timeout_c ount = 0 ; /* we've done well, reset the timeout */
} else {
show_block_marker ( ) ;
}
@ -301,12 +305,12 @@ static void tftp_complete(void)
{
# ifdef CONFIG_TFTP_TSIZE
/* Print hash marks for the last packet received */
while ( TftpTsize & & TftpNumchars < 49 ) {
while ( tftp_tsize & & tftp_tsize_num_hash < 49 ) {
putc ( ' # ' ) ;
TftpNumchars + + ;
tftp_tsize_num_hash + + ;
}
puts ( " " ) ;
print_size ( TftpT size, " " ) ;
print_size ( tftp_t size, " " ) ;
# endif
time_start = get_timer ( time_start ) ;
if ( time_start > 0 ) {
@ -318,8 +322,7 @@ static void tftp_complete(void)
net_set_state ( NETLOOP_SUCCESS ) ;
}
static void
TftpSend ( void )
static void tftp_send ( void )
{
uchar * pkt ;
uchar * xp ;
@ -328,9 +331,8 @@ TftpSend(void)
# ifdef CONFIG_MCAST_TFTP
/* Multicast TFTP.. non-MasterClients do not ACK data. */
if ( Multicast
& & ( TftpState = = STATE_DATA )
& & ( MasterClient = = 0 ) )
if ( tftp_mcast_active & & tftp_state = = STATE_DATA & &
tftp_mcast_master_client = = 0 )
return ;
# endif
/*
@ -339,13 +341,13 @@ TftpSend(void)
*/
pkt = net_tx_packet + net_eth_hdr_size ( ) + IP_UDP_HDR_SIZE ;
switch ( TftpS tate) {
switch ( tftp_s tate) {
case STATE_SEND_RRQ :
case STATE_SEND_WRQ :
xp = pkt ;
s = ( ushort * ) pkt ;
# ifdef CONFIG_CMD_TFTPPUT
* s + + = htons ( TftpS tate = = STATE_SEND_RRQ ? TFTP_RRQ :
* s + + = htons ( tftp_s tate = = STATE_SEND_RRQ ? TFTP_RRQ :
TFTP_WRQ ) ;
# else
* s + + = htons ( TFTP_RRQ ) ;
@ -357,7 +359,7 @@ TftpSend(void)
pkt + = 5 /*strlen("octet")*/ + 1 ;
strcpy ( ( char * ) pkt , " timeout " ) ;
pkt + = 7 /*strlen("timeout")*/ + 1 ;
sprintf ( ( char * ) pkt , " %lu " , TftpTimeoutMSec s / 1000 ) ;
sprintf ( ( char * ) pkt , " %lu " , timeout_m s / 1000 ) ;
debug ( " send option \" timeout %s \" \n " , ( char * ) pkt ) ;
pkt + = strlen ( ( char * ) pkt ) + 1 ;
# ifdef CONFIG_TFTP_TSIZE
@ -366,14 +368,14 @@ TftpSend(void)
# endif
/* try for more effic. blk size */
pkt + = sprintf ( ( char * ) pkt , " blksize%c%d%c " ,
0 , TftpBlkSizeO ption, 0 ) ;
0 , tftp_block_size_o ption, 0 ) ;
# ifdef CONFIG_MCAST_TFTP
/* Check all preconditions before even trying the option */
if ( ! ProhibitMcast ) {
B itmap = malloc ( Map size) ;
if ( B itmap & & eth_get_dev ( ) - > mcast ) {
free ( B itmap) ;
B itmap = NULL ;
if ( ! tftp_mcast_disabled ) {
tftp_mcast_b itmap = malloc ( tftp_mcast_bitmap_ size) ;
if ( tftp_mcast_b itmap & & eth_get_dev ( ) - > mcast ) {
free ( tftp_mcast_b itmap) ;
tftp_mcast_b itmap = NULL ;
pkt + = sprintf ( ( char * ) pkt , " multicast%c%c " ,
0 , 0 ) ;
}
@ -384,11 +386,12 @@ TftpSend(void)
case STATE_OACK :
# ifdef CONFIG_MCAST_TFTP
/* My turn! Start at where I need blocks I missed.*/
if ( Multicast )
TftpBlock = ext2_find_next_zero_bit ( Bitmap ,
( Mapsize * 8 ) , 0 ) ;
/*..falling..*/
/* My turn! Start at where I need blocks I missed. */
if ( tftp_mcast_active )
tftp_cur_block = ext2_find_next_zero_bit (
tftp_mcast_bitmap ,
tftp_mcast_bitmap_size * 8 , 0 ) ;
/* fall through */
# endif
case STATE_RECV_WRQ :
@ -396,16 +399,16 @@ TftpSend(void)
xp = pkt ;
s = ( ushort * ) pkt ;
s [ 0 ] = htons ( TFTP_ACK ) ;
s [ 1 ] = htons ( TftpB lock) ;
s [ 1 ] = htons ( tftp_cur_b lock) ;
pkt = ( uchar * ) ( s + 2 ) ;
# ifdef CONFIG_CMD_TFTPPUT
if ( TftpWriting ) {
int toload = TftpBlkS ize;
int loaded = load_block ( TftpB lock, pkt , toload ) ;
if ( tftp_put_active ) {
int toload = tftp_block_s ize;
int loaded = load_block ( tftp_cur_b lock, pkt , toload ) ;
s [ 0 ] = htons ( TFTP_DATA ) ;
pkt + = loaded ;
TftpFinalBlock = ( loaded < toload ) ;
tftp_put_final_block_sent = ( loaded < toload ) ;
}
# endif
len = pkt - xp ;
@ -435,8 +438,8 @@ TftpSend(void)
break ;
}
net_send_udp_packet ( net_server_ethaddr , tftp_remote_ip , TftpRemotePort ,
TftpOurP ort, len ) ;
net_send_udp_packet ( net_server_ethaddr , tftp_remote_ip ,
tftp_remote_port , tftp_our_p ort, len ) ;
}
# ifdef CONFIG_CMD_TFTPPUT
@ -458,15 +461,15 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
__be16 * s ;
int i ;
if ( dest ! = TftpOurP ort) {
if ( dest ! = tftp_our_p ort) {
# ifdef CONFIG_MCAST_TFTP
if ( Multicast
& & ( ! M cast_port | | ( dest ! = Mcast_port ) ) )
if ( tftp_mcast_active & &
( ! tftp_m cast_port | | dest ! = tftp_mcast_port ) )
# endif
return ;
}
if ( TftpS tate ! = STATE_SEND_RRQ & & src ! = TftpRemoteP ort & &
TftpS tate ! = STATE_RECV_WRQ & & TftpS tate ! = STATE_SEND_WRQ )
if ( tftp_s tate ! = STATE_SEND_RRQ & & src ! = tftp_remote_p ort & &
tftp_s tate ! = STATE_RECV_WRQ & & tftp_s tate ! = STATE_SEND_WRQ )
return ;
if ( len < 2 )
@ -477,14 +480,13 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
proto = * s + + ;
pkt = ( uchar * ) s ;
switch ( ntohs ( proto ) ) {
case TFTP_RRQ :
break ;
case TFTP_ACK :
# ifdef CONFIG_CMD_TFTPPUT
if ( TftpWriting ) {
if ( TftpFinalBlock ) {
if ( tftp_put_active ) {
if ( tftp_put_final_block_sent ) {
tftp_complete ( ) ;
} else {
/*
@ -492,12 +494,12 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
* count to wrap just like the other end !
*/
int block = ntohs ( * s ) ;
int ack_ok = ( TftpB lock = = block ) ;
int ack_ok = ( tftp_cur_b lock = = block ) ;
TftpB lock = ( unsigned short ) ( block + 1 ) ;
tftp_cur_b lock = ( unsigned short ) ( block + 1 ) ;
update_block_number ( ) ;
if ( ack_ok )
TftpS end( ) ; /* Send next data block */
tftp_s end( ) ; /* Send next data block */
}
}
# endif
@ -510,101 +512,98 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
case TFTP_WRQ :
debug ( " Got WRQ \n " ) ;
tftp_remote_ip = sip ;
TftpRemoteP ort = src ;
TftpOurP ort = 1024 + ( get_timer ( 0 ) % 3072 ) ;
tftp_remote_p ort = src ;
tftp_our_p ort = 1024 + ( get_timer ( 0 ) % 3072 ) ;
new_transfer ( ) ;
TftpS end( ) ; /* Send ACK(0) */
tftp_s end( ) ; /* Send ACK(0) */
break ;
# endif
case TFTP_OACK :
debug ( " Got OACK: %s %s \n " ,
pkt ,
pkt + strlen ( ( char * ) pkt ) + 1 ) ;
TftpState = STATE_OACK ;
TftpRemotePort = src ;
pkt , pkt + strlen ( ( char * ) pkt ) + 1 ) ;
tftp_state = STATE_OACK ;
tftp_remote_port = src ;
/*
* Check for ' blksize ' option .
* Careful : " i " is signed , " len " is unsigned , thus
* something like " len-8 " may give a * huge * number
*/
for ( i = 0 ; i + 8 < len ; i + + ) {
if ( strcmp ( ( char * ) pkt + i , " blksize " ) = = 0 ) {
TftpBlkS ize = ( unsigned short )
simple_strtoul ( ( char * ) pkt + i + 8 , NULL ,
10 ) ;
if ( strcmp ( ( char * ) pkt + i , " blksize " ) = = 0 ) {
tftp_block_s ize = ( unsigned short )
simple_strtoul ( ( char * ) pkt + i + 8 ,
NULL , 10 ) ;
debug ( " Blocksize ack: %s, %d \n " ,
( char * ) pkt + i + 8 , TftpBlkS ize) ;
( char * ) pkt + i + 8 , tftp_block_s ize) ;
}
# ifdef CONFIG_TFTP_TSIZE
if ( strcmp ( ( char * ) pkt + i , " tsize " ) = = 0 ) {
TftpT size = simple_strtoul ( ( char * ) pkt + i + 6 ,
tftp_t size = simple_strtoul ( ( char * ) pkt + i + 6 ,
NULL , 10 ) ;
debug ( " size = %s, %d \n " ,
( char * ) pkt + i + 6 , TftpT size) ;
( char * ) pkt + i + 6 , tftp_t size) ;
}
# endif
}
# ifdef CONFIG_MCAST_TFTP
parse_multicast_oack ( ( char * ) pkt , len - 1 ) ;
if ( ( Multicast ) & & ( ! MasterC lient) )
TftpS tate = STATE_DATA ; /* passive.. */
parse_multicast_oack ( ( char * ) pkt , len - 1 ) ;
if ( ( tftp_mcast_active ) & & ( ! tftp_mcast_master_c lient) )
tftp_s tate = STATE_DATA ; /* passive.. */
else
# endif
# ifdef CONFIG_CMD_TFTPPUT
if ( TftpWriting ) {
if ( tftp_put_active ) {
/* Get ready to send the first block */
TftpS tate = STATE_DATA ;
TftpB lock+ + ;
tftp_s tate = STATE_DATA ;
tftp_cur_b lock+ + ;
}
# endif
TftpS end( ) ; /* Send ACK or first data block */
tftp_s end( ) ; /* Send ACK or first data block */
break ;
case TFTP_DATA :
if ( len < 2 )
return ;
len - = 2 ;
TftpB lock = ntohs ( * ( __be16 * ) pkt ) ;
tftp_cur_b lock = ntohs ( * ( __be16 * ) pkt ) ;
update_block_number ( ) ;
if ( TftpS tate = = STATE_SEND_RRQ )
if ( tftp_s tate = = STATE_SEND_RRQ )
debug ( " Server did not acknowledge timeout option! \n " ) ;
if ( TftpS tate = = STATE_SEND_RRQ | | TftpS tate = = STATE_OACK | |
TftpS tate = = STATE_RECV_WRQ ) {
if ( tftp_s tate = = STATE_SEND_RRQ | | tftp_s tate = = STATE_OACK | |
tftp_s tate = = STATE_RECV_WRQ ) {
/* first block received */
TftpS tate = STATE_DATA ;
TftpRemoteP ort = src ;
tftp_s tate = STATE_DATA ;
tftp_remote_p ort = src ;
new_transfer ( ) ;
# ifdef CONFIG_MCAST_TFTP
if ( Multicast ) { /* start!=1 common if mcast */
TftpLastBlock = TftpB lock - 1 ;
if ( tftp_mcast_active ) { /* start!=1 common if mcast */
tftp_prev_block = tftp_cur_b lock - 1 ;
} else
# endif
if ( TftpB lock ! = 1 ) { /* Assertion */
printf ( " \n TFTP error: "
" First block is not block 1 (%ld) \n "
" Starting again \n \n " ,
TftpBlock ) ;
if ( tftp_cur_b lock ! = 1 ) { /* Assertion */
puts ( " \n TFTP error: " ) ;
printf ( " First block is not block 1 (%ld) \n " ,
tftp_cur_block ) ;
puts ( " Starting again \n \n " ) ;
NetStartAgain ( ) ;
break ;
}
}
if ( TftpBlock = = TftpLastBlock ) {
/*
* Same block again ; ignore it .
*/
if ( tftp_cur_block = = tftp_prev_block ) {
/* Same block again; ignore it. */
break ;
}
TftpLastBlock = TftpB lock;
TftpTimeoutCountM ax = TIMEOUT_COUNT ;
NetSetTimeout ( TftpTimeoutMSecs , TftpTimeout ) ;
tftp_prev_block = tftp_cur_b lock;
timeout_count_m ax = TIMEOUT_COUNT ;
NetSetTimeout ( timeout_ms , tftp_timeout_handler ) ;
store_block ( TftpB lock - 1 , pkt + 2 , len ) ;
store_block ( tftp_cur_b lock - 1 , pkt + 2 , len ) ;
/*
* Acknowledge the block just received , which will prompt
@ -614,39 +613,41 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
/* if I am the MasterClient, actively calculate what my next
* needed block is ; else I ' m passive ; not ACKING
*/
if ( Multicast ) {
if ( len < TftpBlkSize ) {
TftpEndingBlock = TftpBlock ;
} else if ( MasterClient ) {
TftpBlock = PrevBitmapHole =
ext2_find_next_zero_bit (
Bitmap ,
( Mapsize * 8 ) ,
PrevBitmapHole ) ;
if ( TftpBlock > ( ( Mapsize * 8 ) - 1 ) ) {
printf ( " tftpfile too big \n " ) ;
if ( tftp_mcast_active ) {
if ( len < tftp_block_size ) {
tftp_mcast_ending_block = tftp_cur_block ;
} else if ( tftp_mcast_master_client ) {
tftp_mcast_prev_hole = ext2_find_next_zero_bit (
tftp_mcast_bitmap ,
tftp_mcast_bitmap_size * 8 ,
tftp_mcast_prev_hole ) ;
tftp_cur_block = tftp_mcast_prev_hole ;
if ( tftp_cur_block >
( ( tftp_mcast_bitmap_size * 8 ) - 1 ) ) {
debug ( " tftpfile too big \n " ) ;
/* try to double it and retry */
Map size < < = 1 ;
tftp_mcast_bitmap_ size < < = 1 ;
mcast_cleanup ( ) ;
NetStartAgain ( ) ;
return ;
}
TftpLastBlock = TftpB lock;
tftp_prev_block = tftp_cur_b lock;
}
}
# endif
TftpS end( ) ;
tftp_s end( ) ;
# ifdef CONFIG_MCAST_TFTP
if ( Multicast ) {
if ( MasterClient & & ( TftpBlock > = TftpEndingBlock ) ) {
if ( tftp_mcast_active ) {
if ( tftp_mcast_master_client & &
( tftp_cur_block > = tftp_mcast_ending_block ) ) {
puts ( " \n Multicast tftp done \n " ) ;
mcast_cleanup ( ) ;
net_set_state ( NETLOOP_SUCCESS ) ;
}
} else
# endif
if ( len < TftpBlkS ize)
if ( len < tftp_block_s ize)
tftp_complete ( ) ;
break ;
@ -679,21 +680,20 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
}
static void
TftpTimeout ( void )
static void tftp_timeout_handler ( void )
{
if ( + + TftpTimeoutCount > TftpTimeoutCountM ax) {
if ( + + timeout_count > timeout_count_m ax) {
restart ( " Retry count exceeded " ) ;
} else {
puts ( " T " ) ;
NetSetTimeout ( TftpTimeoutMSecs , TftpTimeout ) ;
if ( TftpS tate ! = STATE_RECV_WRQ )
TftpS end( ) ;
NetSetTimeout ( timeout_ms , tftp_timeout_handler ) ;
if ( tftp_s tate ! = STATE_RECV_WRQ )
tftp_s end( ) ;
}
}
void TftpS tart( enum proto_t protocol )
void tftp_s tart( enum proto_t protocol )
{
char * ep ; /* Environment pointer */
@ -703,21 +703,20 @@ void TftpStart(enum proto_t protocol)
*/
ep = getenv ( " tftpblocksize " ) ;
if ( ep ! = NULL )
TftpBlkSizeO ption = simple_strtol ( ep , NULL , 10 ) ;
tftp_block_size_o ption = simple_strtol ( ep , NULL , 10 ) ;
ep = getenv ( " tftptimeout " ) ;
if ( ep ! = NULL )
TftpTimeoutMSec s = simple_strtol ( ep , NULL , 10 ) ;
timeout_m s = simple_strtol ( ep , NULL , 10 ) ;
if ( TftpTimeoutMSecs < 1000 ) {
printf ( " TFTP timeout (%ld ms) too low, "
" set minimum = 1000 ms \n " ,
TftpTimeoutMSecs ) ;
TftpTimeoutMSecs = 1000 ;
if ( timeout_ms < 1000 ) {
printf ( " TFTP timeout (%ld ms) too low, set min = 1000 ms \n " ,
timeout_ms ) ;
timeout_ms = 1000 ;
}
debug ( " TFTP blocksize = %i, timeout = %ld ms \n " ,
TftpBlkSizeOption , TftpTimeoutMSec s ) ;
tftp_block_size_option , timeout_m s ) ;
tftp_remote_ip = net_server_ip ;
if ( net_boot_file_name [ 0 ] = = ' \0 ' ) {
@ -728,20 +727,20 @@ void TftpStart(enum proto_t protocol)
( net_ip . s_addr > > 24 ) & 0xFF ) ;
strncpy ( tftp_filename , default_filename , MAX_LEN ) ;
tftp_filename [ MAX_LEN - 1 ] = 0 ;
tftp_filename [ MAX_LEN - 1 ] = 0 ;
printf ( " *** Warning: no boot file name; using '%s' \n " ,
tftp_filename ) ;
tftp_filename ) ;
} else {
char * p = strchr ( net_boot_file_name , ' : ' ) ;
if ( p = = NULL ) {
strncpy ( tftp_filename , net_boot_file_name , MAX_LEN ) ;
tftp_filename [ MAX_LEN - 1 ] = 0 ;
tftp_filename [ MAX_LEN - 1 ] = 0 ;
} else {
tftp_remote_ip = string_to_ip ( net_boot_file_name ) ;
strncpy ( tftp_filename , p + 1 , MAX_LEN ) ;
tftp_filename [ MAX_LEN - 1 ] = 0 ;
tftp_filename [ MAX_LEN - 1 ] = 0 ;
}
}
@ -750,9 +749,9 @@ void TftpStart(enum proto_t protocol)
# ifdef CONFIG_CMD_TFTPPUT
protocol = = TFTPPUT ? " to " : " from " ,
# else
" from " ,
" from " ,
# endif
& tftp_remote_ip , & net_ip ) ;
& tftp_remote_ip , & net_ip ) ;
/* Check if we need to send across this subnet */
if ( net_gateway . s_addr & & net_netmask . s_addr ) {
@ -776,63 +775,62 @@ void TftpStart(enum proto_t protocol)
putc ( ' \n ' ) ;
# ifdef CONFIG_CMD_TFTPPUT
TftpWriting = ( protocol = = TFTPPUT ) ;
if ( TftpWriting ) {
tftp_put_active = ( protocol = = TFTPPUT ) ;
if ( tftp_put_active ) {
printf ( " Save address: 0x%lx \n " , save_addr ) ;
printf ( " Save size: 0x%lx \n " , save_size ) ;
net_boot_file_size = save_size ;
puts ( " Saving: * \b " ) ;
TftpS tate = STATE_SEND_WRQ ;
tftp_s tate = STATE_SEND_WRQ ;
new_transfer ( ) ;
} else
# endif
{
printf ( " Load address: 0x%lx \n " , load_addr ) ;
puts ( " Loading: * \b " ) ;
TftpS tate = STATE_SEND_RRQ ;
tftp_s tate = STATE_SEND_RRQ ;
}
time_start = get_timer ( 0 ) ;
TftpTimeoutCountMax = TftpRRQTimeoutCountM ax;
timeout_count_max = tftp_timeout_count_m ax;
NetSetTimeout ( TftpTimeoutMSecs , TftpTimeout ) ;
NetSetTimeout ( timeout_ms , tftp_timeout_handler ) ;
net_set_udp_handler ( tftp_handler ) ;
# ifdef CONFIG_CMD_TFTPPUT
net_set_icmp_handler ( icmp_handler ) ;
# endif
TftpRemoteP ort = WELL_KNOWN_PORT ;
TftpTimeoutC ount = 0 ;
tftp_remote_p ort = WELL_KNOWN_PORT ;
timeout_c ount = 0 ;
/* Use a pseudo-random port unless a specific port is set */
TftpOurP ort = 1024 + ( get_timer ( 0 ) % 3072 ) ;
tftp_our_p ort = 1024 + ( get_timer ( 0 ) % 3072 ) ;
# ifdef CONFIG_TFTP_PORT
ep = getenv ( " tftpdstp " ) ;
if ( ep ! = NULL )
TftpRemoteP ort = simple_strtol ( ep , NULL , 10 ) ;
tftp_remote_p ort = simple_strtol ( ep , NULL , 10 ) ;
ep = getenv ( " tftpsrcp " ) ;
if ( ep ! = NULL )
TftpOurP ort = simple_strtol ( ep , NULL , 10 ) ;
tftp_our_p ort = simple_strtol ( ep , NULL , 10 ) ;
# endif
TftpB lock = 0 ;
tftp_cur_b lock = 0 ;
/* zero out server ether in case the server ip has changed */
memset ( net_server_ethaddr , 0 , 6 ) ;
/* Revert TftpBlkS ize to dflt */
TftpBlkS ize = TFTP_BLOCK_SIZE ;
/* Revert tftp_block_s ize to dflt */
tftp_block_s ize = TFTP_BLOCK_SIZE ;
# ifdef CONFIG_MCAST_TFTP
mcast_cleanup ( ) ;
# endif
# ifdef CONFIG_TFTP_TSIZE
TftpT size = 0 ;
TftpNumchars = 0 ;
tftp_t size = 0 ;
tftp_tsize_num_hash = 0 ;
# endif
TftpS end( ) ;
tftp_s end( ) ;
}
# ifdef CONFIG_CMD_TFTPSRV
void
TftpStartServer ( void )
void tftp_start_server ( void )
{
tftp_filename [ 0 ] = 0 ;
@ -842,22 +840,22 @@ TftpStartServer(void)
puts ( " Loading: * \b " ) ;
TftpTimeoutCountM ax = TIMEOUT_COUNT ;
TftpTimeoutC ount = 0 ;
TftpTimeoutMSec s = TIMEOUT ;
NetSetTimeout ( TftpTimeoutMSecs , TftpTimeout ) ;
timeout_count_m ax = TIMEOUT_COUNT ;
timeout_c ount = 0 ;
timeout_m s = TIMEOUT ;
NetSetTimeout ( timeout_ms , tftp_timeout_handler ) ;
/* Revert TftpBlkS ize to dflt */
TftpBlkS ize = TFTP_BLOCK_SIZE ;
TftpB lock = 0 ;
TftpOurP ort = WELL_KNOWN_PORT ;
/* Revert tftp_block_s ize to dflt */
tftp_block_s ize = TFTP_BLOCK_SIZE ;
tftp_cur_b lock = 0 ;
tftp_our_p ort = WELL_KNOWN_PORT ;
# ifdef CONFIG_TFTP_TSIZE
TftpT size = 0 ;
TftpNumchars = 0 ;
tftp_t size = 0 ;
tftp_tsize_num_hash = 0 ;
# endif
TftpS tate = STATE_RECV_WRQ ;
tftp_s tate = STATE_RECV_WRQ ;
net_set_udp_handler ( tftp_handler ) ;
/* zero out server ether in case the server ip has changed */
@ -866,10 +864,12 @@ TftpStartServer(void)
# endif /* CONFIG_CMD_TFTPSRV */
# ifdef CONFIG_MCAST_TFTP
/* Credits: atftp project.
/*
* Credits : atftp project .
*/
/* pick up BcastAddr, Port, and whether I am [now] the master-client. *
/*
* Pick up BcastAddr , Port , and whether I am [ now ] the master - client .
* Frame :
* + - - - - - - - + - - - - - - - - - - - + - - - + - - - - - - - ~ ~ - - - - - - - + - - - +
* | opc | multicast | 0 | addr , port , mc | 0 |
@ -885,58 +885,62 @@ static void parse_multicast_oack(char *pkt, int len)
{
int i ;
struct in_addr addr ;
char * mc_adr , * port , * mc ;
char * mc_adr ;
char * port ;
char * mc ;
mc_adr = port = mc = NULL ;
mc_adr = NULL ;
port = NULL ;
mc = NULL ;
/* march along looking for 'multicast\0', which has to start at least
* 14 bytes back from the end .
*/
for ( i = 0 ; i < len - 14 ; i + + )
if ( strcmp ( pkt + i , " multicast " ) = = 0 )
for ( i = 0 ; i < len - 14 ; i + + )
if ( strcmp ( pkt + i , " multicast " ) = = 0 )
break ;
if ( i > = ( len - 14 ) ) /* non-Multicast OACK, ign. */
if ( i > = ( len - 14 ) ) /* non-Multicast OACK, ign. */
return ;
i + = 10 ; /* strlen multicast */
mc_adr = pkt + i ;
mc_adr = pkt + i ;
for ( ; i < len ; i + + ) {
if ( * ( pkt + i ) = = ' , ' ) {
* ( pkt + i ) = ' \0 ' ;
if ( * ( pkt + i ) = = ' , ' ) {
* ( pkt + i ) = ' \0 ' ;
if ( port ) {
mc = pkt + i + 1 ;
mc = pkt + i + 1 ;
break ;
} else {
port = pkt + i + 1 ;
port = pkt + i + 1 ;
}
}
}
if ( ! port | | ! mc_adr | | ! mc )
return ;
if ( Multicast & & MasterC lient) {
if ( tftp_mcast_active & & tftp_mcast_master_c lient) {
printf ( " I got a OACK as master Client, WRONG! \n " ) ;
return ;
}
/* ..I now accept packets destined for this MCAST addr, port */
if ( ! Multicast ) {
if ( B itmap) {
if ( ! tftp_mcast_active ) {
if ( tftp_mcast_b itmap) {
printf ( " Internal failure! no mcast. \n " ) ;
free ( B itmap) ;
B itmap = NULL ;
ProhibitMcast = 1 ;
return ;
free ( tftp_mcast_b itmap) ;
tftp_mcast_b itmap = NULL ;
tftp_mcast_disabled = 1 ;
return ;
}
/* I malloc instead of pre-declare; so that if the file ends
* up being too big for this bitmap I can retry
*/
B itmap = malloc ( Map size) ;
if ( ! B itmap) {
printf ( " No B itmap, no multicast. Sorry. \n " ) ;
ProhibitMcast = 1 ;
tftp_mcast_b itmap = malloc ( tftp_mcast_bitmap_ size) ;
if ( ! tftp_mcast_b itmap) {
printf ( " No b itmap, no multicast. Sorry. \n " ) ;
tftp_mcast_disabled = 1 ;
return ;
}
memset ( B itmap, 0 , Map size) ;
PrevBitmapH ole = 0 ;
Multicast = 1 ;
memset ( tftp_mcast_b itmap, 0 , tftp_mcast_bitmap_ size) ;
tftp_mcast_prev_h ole = 0 ;
tftp_mcast_active = 1 ;
}
addr = string_to_ip ( mc_adr ) ;
if ( net_mcast_addr . s_addr ! = addr . s_addr ) {
@ -945,14 +949,15 @@ static void parse_multicast_oack(char *pkt, int len)
net_mcast_addr = addr ;
if ( eth_mcast_join ( net_mcast_addr , 1 ) ) {
printf ( " Fail to set mcast, revert to TFTP \n " ) ;
ProhibitMcast = 1 ;
tftp_mcast_disabled = 1 ;
mcast_cleanup ( ) ;
NetStartAgain ( ) ;
}
}
MasterClient = ( unsigned char ) simple_strtoul ( ( char * ) mc , NULL , 10 ) ;
Mcast_port = ( unsigned short ) simple_strtoul ( port , NULL , 10 ) ;
printf ( " Multicast: %s:%d [%d] \n " , mc_adr , Mcast_port , MasterClient ) ;
tftp_mcast_master_client = simple_strtoul ( ( char * ) mc , NULL , 10 ) ;
tftp_mcast_port = ( unsigned short ) simple_strtoul ( port , NULL , 10 ) ;
printf ( " Multicast: %s:%d [%d] \n " , mc_adr , tftp_mcast_port ,
tftp_mcast_master_client ) ;
return ;
}