📄 net_tftpc.c
字号:
if (opcode == TFTP_HEADER_OPCODE_ERROR)
{
if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_BLOCK)
{
/* save HOST error */
sap_context.host_error = tmp2 ;
data[length] = 0 ;
strcpy( sap_context.host_error_msg,
&data[TFTP_HEADER_BASE + TFTP_HEADER_ERRORMSG] ) ;
sprintf( net_diag_msg, "Host returned: ErrorCode = %d, ErrorMsg = %s",
sap_context.host_error,
sap_context.host_error_msg );
sap_context.error_cause = ERROR_NET_TFTP_READ_ERROR ;
}
if ( (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_NEXT_BLOCK) ||
(sap_context.sap_state == TFTPC_SAP_STATE_CONGESTION) ||
(sap_context.sap_state == TFTPC_SAP_STATE_LAST_BLOCK_READ) )
{
/* validate 'src_port' */
if (sap_context.dst_port != src_port)
{
/* We should just ignore this packet, */
/* do nothing */
return( ERROR_NET_TFTPC_INVALID_TID ) ;
}
/* save HOST error */
sap_context.host_error = tmp2 ;
data[length] = 0 ;
strcpy( sap_context.host_error_msg,
&data[TFTP_HEADER_BASE + TFTP_HEADER_ERRORMSG] ) ;
sprintf( net_diag_msg, "Host returned: ErrorCode = %d, ErrorMsg = %s",
sap_context.host_error,
sap_context.host_error_msg );
sap_context.error_cause = ERROR_NET_TFTP_DATA_ERROR ;
}
/* New state: 'ERROR' */
sap_context.sap_state = TFTPC_SAP_STATE_ERROR ;
}
/* return, despite if it is not DATA */
return( sap_context.error_cause ) ;
}
/* We have 'DATA' */
/* Check for 1. Block data and save 'src_port', and src-MAC */
if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_BLOCK)
{
sap_context.dst_port = src_port ;
memcpy( &sap_context.dst_mac_adr,
src_mac_adr,
SYS_MAC_ADDR_SIZE ) ;
}
else
{
/* validate 'src_port' */
if (sap_context.dst_port != src_port)
{
/* We should just ignore this packet, */
/* do nothing */
return( ERROR_NET_TFTPC_INVALID_TID ) ;
}
}
/* 'TID' is valid */
/* Validate block number */
if (tmp2 != (UINT16)(sap_context.block_number + 1) )
{
#if 0
if (tmp2 == TFTP_HEADER_MAX_BLOCKNUMBER)
{
/* New state: 'ERROR' */
sap_context.sap_state = TFTPC_SAP_STATE_ERROR ;
sap_context.error_cause = ERROR_NET_TFTP_FILE_TOO_BIG ;
return( ERROR_NET_TFTP_FILE_TOO_BIG ) ;
}
#endif
/* To avoid the "Sorcerer's Apprentice: do nothing and let timer
retransmit if host doesn't */
return( ERROR_NET_TFTPC_INVALID_BLOCK_NUMBER ) ;
#ifdef NET_ENABLE_TFTPC_INVALID_BLOCK_NUMBER
if (tmp2 == sap_context.block_number)
{
/* This is the case, when an 'ACK' has got lost */
/* Send 'ACK' */
rcode = NET_TFTPC_sendACK( &sap_context ) ;
return( rcode ) ;
}
else
{
/* New state: 'ERROR' */
sap_context.sap_state = TFTPC_SAP_STATE_ERROR ;
sap_context.error_cause = ERROR_NET_TFTPC_INVALID_BLOCK_NUMBER ;
return( ERROR_NET_TFTPC_INVALID_BLOCK_NUMBER ) ;
}
#endif
}
/* Try to save data into our buffer */
tftp_data_length = length - (MAC_HEADER_SIZE + IP_HEADER_SIZE +
UDP_HEADER_SIZE + TFTP_HEADER_DATA) ;
/* No data, re-evaluate buffer status */
index = sap_context.write_idx ;
if ( sap_context.buf[ index ].ctrl == BUFFER_STATE_EMPTY )
{
/* we seem to have an empty buffer */
/* OK, send ACK now */
sap_context.block_number = tmp2 ;
rcode = NET_TFTPC_sendACK( &sap_context ) ;
/* save data */
memcpy( sap_context.buf[ index ].blink,
&data[ TFTP_HEADER_BASE + TFTP_HEADER_DATA ],
tftp_data_length ) ;
/* update context */
sap_context.buf[ index ].count = tftp_data_length ;
sap_context.buf[ index ].ctrl = BUFFER_STATE_FULL ;
/* proceed to next buffer */
sap_context.write_idx++ ;
if (sap_context.write_idx == TFTPC_SAP_BUFFER_COUNT)
{
sap_context.write_idx = 0 ;
}
if (tftp_data_length < TFTP_HEADER_DATA_MAX_SIZE)
{
/* Set state 'LAST_BLOCK_READ' */
sap_context.sap_state = TFTPC_SAP_STATE_LAST_BLOCK_READ ;
}
else
{
/* Set timer and retry count */
/* get time now (unit is seconds since 1.1.1970) */
NET_gettime( &sap_context.timeout ) ;
sap_context.timeout = sap_context.timeout + TFTPC_SAP_TIMEOUT ;
sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ;
/* Set state 'WAIT_NEXT_BLOCK' */
sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_BLOCK ;
}
rcode = OK ;
}
else
{
/* Set state 'CONGESTION' */
sap_context.sap_state = TFTPC_SAP_STATE_CONGESTION ;
rcode = ERROR_NET_TFTPC_CONGESTION ;
}
return( rcode ) ;
}
/************************************************************************
*
* NET_TFTPC_init_sap
* Description :
* -------------
* Initialize the TFTPC SAP context.
*
*
* Parameters :
* ------------
* -
*
*
* Return values :
* ---------------
* 'OK'(=0), successfull initialization
*
************************************************************************/
static
UINT32 NET_TFTPC_init_sap( t_tftpc_sap_context *context )
{
UINT32 rcode ;
/* initialize SAP */
/* bind this SAP to UDP and let UDP allocate a unique port */
rcode = NET_UDP_open( UDP_SAP_UNDEFINED,
NET_TFTPC_receive_data_byte,
&(context->udp_sp_hd) ) ;
if (rcode == OK)
{
/* New state 'BOUND_TO_UDP' */
context->sap_state = TFTPC_SAP_STATE_BOUND_TO_UDP ;
/* Reset context */
rcode = NET_TFTPC_reset_sap( context, NET_TFTPC_receive_data_byte ) ;
}
else
{
/* New state 'IDLE' */
context->sap_state = TFTPC_SAP_STATE_IDLE ;
}
return( rcode ) ;
}
/************************************************************************
*
* NET_TFTPC_reset_sap
* Description :
* -------------
* Reset the TFTPC SAP context.
*
*
* Parameters :
* ------------
* -
*
*
* Return values :
* ---------------
* 'OK'(=0), successfull initialization
*
************************************************************************/
static
UINT32 NET_TFTPC_reset_sap( t_tftpc_sap_context *context,
t_udp_usr_receive rec )
{
UINT32 rcode = OK ;
int i ;
/* Reset SAP */
if (context->sap_state != TFTPC_SAP_STATE_IDLE)
{
/* re-allocate a new UDP SAP */
IF_ERROR( (rcode),
(NET_UDP_close( context->udp_sp_hd ) ) )
IF_ERROR( (rcode),
(NET_UDP_open( UDP_SAP_UNDEFINED,
rec,
&(context->udp_sp_hd) ) ) )
/* clean up context */
context->dst_ip_adr = IP_ADDR_UNDEFINED ;
context->dst_port = CPU_TO_BE16( UDP_SAP_TFTP ) ;
memcpy( context->dst_mac_adr, &mac_undefined_adr, SYS_MAC_ADDR_SIZE) ;
context->block_number = 0 ;
context->timeout = 0 ;
context->retry_left = 0 ;
context->error_cause = OK ;
context->send_rc = OK ;
context->host_error = 0 ;
context->host_error_msg = context->data ;
context->filename = context->data ;
context->pread = NULL ;
context->puser = NULL ;
context->user_size = 0 ;
context->bytes_left = 0 ;
context->read_idx = 0 ;
context->write_idx = 0 ;
context->sap_state = TFTPC_SAP_STATE_BOUND_TO_UDP ;
}
for (i=0; i<TFTPC_SAP_BUFFER_COUNT; i++)
{
context->buf[i].ctrl = BUFFER_STATE_EMPTY ;
context->buf[i].count = 0 ;
}
return( rcode ) ;
}
/************************************************************************
*
* NET_TFTPC_sendDATA
* Description :
* -------------
* Send 'DATA' of this SAP context.
*
*
* Parameters :
* ------------
* -
*
*
* Return values :
* ---------------
* 'OK'(=0),
*
************************************************************************/
static
UINT32 NET_TFTPC_sendDATA( t_tftpc_sap_context *context )
{
UINT8 data[TFTP_HEADER_BASE+TFTP_HEADER_DATA_MAX_HEADER_SIZE] ;
UINT8 *p ;
UINT16 tmp2 ;
UINT32 length, i ;
/* build the 'TFTP-DATA' header */
p = &data[ TFTP_HEADER_BASE + TFTP_HEADER_OPCODE ] ;
tmp2 = CPU_TO_BE16( TFTP_HEADER_OPCODE_DATA ) ;
put2( tmp2, p )
tmp2 = CPU_TO_BE16( context->block_number ) ;
put2( tmp2, p )
if ( context->bytes_left > TFTP_HEADER_DATA_MAX_SIZE )
{
length = TFTP_HEADER_DATA_MAX_SIZE ;
}
else
{
length = context->bytes_left ;
}
if (length > 0)
{
memcpy( &data[TFTP_HEADER_BASE + TFTP_HEADER_DATA], context->puser, length ) ;
}
length = MAC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE + TFTP_HEADER_DATA + length ;
#ifdef NET_DEBUG
printf("NET_TFTPC_sendDATA\n") ;
printf("dst_ip_adr = %x\n", (unsigned)(BE32_TO_CPU(context->dst_ip_adr)) ) ;
printf("dst_port = %d\n", (unsigned)(BE16_TO_CPU(context->dst_port)) ) ;
printf("block nr. = %d\n", (unsigned) context->block_number ) ;
printf("bytes_left = %d\n", (unsigned) context->bytes_left ) ;
printf("length = %d\n", (unsigned) length ) ;
#endif
/* request UDP to 'send' TFTP DATA */
context->send_rc = NET_UDP_send( context->dst_ip_adr, /* destination ip address (BE) */
context->dst_port, /* destination (TFTP) port (BE)*/
NULL, /* optional MAC destination */
context->udp_sp_hd, /* handle returned of 'open' */
length, /* total length of frame to send */
data ); /* pointer to start of frame */
#ifdef NET_DEBUG
p = data ;
printf("NET_MAC_send:") ;
for (i=0; i<length; i++)
{
if (i%16 == 0)
{
printf("\n %02x",*p++ ) ;
}
else
{
printf(" %02x",*p++ ) ;
}
}
printf("\n" ) ;
#endif
return( context->send_rc ) ;
}
/************************************************************************
*
* NET_TFTPC_sendRRQ
* Description :
* -------------
* Send 'RRQ' of this SAP context.
*
*
* Parameters :
* ------------
* -
*
*
* Return values :
* ---------------
* 'OK'(=0),
*
************************************************************************/
static
UINT32 NET_TFTPC_sendRRQ( t_tftpc_sap_context *context )
{
UINT8 data[TFTP_HEADER_BASE+TFTP_HEADER_RRQ_MAX_HEADER_SIZE] ;
UINT8 *p ;
UINT16 tmp2 ;
UINT32 length ;
/* build the 'TFTP-RRQ' header */
p = &data[ TFTP_HEADER_BASE + TFTP_HEADER_OPCODE ] ;
tmp2 = CPU_TO_BE16( TFTP_HEADER_OPCODE_RRQ ) ;
put2( tmp2, p )
/* copy filename + mode */
tmp2 = strlen(context->filename) + TFTP_HEADER_MODE_OCTET_SIZE ;
memcpy( &data[TFTP_HEADER_BASE + TFTP_HEADER_FILENAME], context->filename, tmp2 ) ;
length = MAC_HEADER_SIZE + IP_HEADER_SIZE + UDP_HEADER_SIZE +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -