📄 net_tftpc.c
字号:
/* do nothing */
return( ERROR_NET_TFTPC_INVALID_TID ) ;
}
}
/* 'TID' is valid */
/* Validate block number */
if (tmp2 != sap_context.block_number)
{
#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 ) ;
}
if ( sap_context.bytes_left < TFTP_HEADER_DATA_MAX_SIZE )
{
if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK)
{
/* OK, proceed to send first (and last) block */
sap_context.block_number++ ;
/* 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_ACK' */
sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_ACK ;
/* Send DATA */
rcode = NET_TFTPC_sendDATA( &sap_context ) ;
}
else
{
/* Last block has been acknowledged */
/* update context */
sap_context.puser = sap_context.puser + sap_context.bytes_left ;
sap_context.bytes_left = 0 ;
/* Set state 'LAST_BLOCK_WRITE' */
sap_context.sap_state = TFTPC_SAP_STATE_LAST_BLOCK_WRITE ;
}
}
else
{
if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK)
{
/* OK, proceed to send first (full) block */
sap_context.block_number++ ;
/* 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_ACK' */
sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_ACK ;
/* Send DATA */
rcode = NET_TFTPC_sendDATA( &sap_context ) ;
}
else
{
/* OK, we have just sent a full block, update context */
sap_context.bytes_left = sap_context.bytes_left - TFTP_HEADER_DATA_MAX_SIZE ;
sap_context.puser = sap_context.puser + TFTP_HEADER_DATA_MAX_SIZE ;
/* OK, proceed to send next block */
sap_context.block_number++ ;
/* 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_ACK' */
sap_context.sap_state = TFTPC_SAP_STATE_WAIT_NEXT_ACK ;
/* Send DATA */
rcode = NET_TFTPC_sendDATA( &sap_context ) ;
}
}
return( rcode ) ;
}
/************************************************************************
*
* NET_TFTPC_receive_data_block
* Description :
* -------------
* This function is registered in the UDP-module and linked with a
* unique UDP-'port', idnetifying our SAP. This allows the UDP to call
* us back with an reference to the received frame,
* containing a TFTP-frame.
*
*
*
* Parameters :
* ------------
* 'src_ip_adr': senders IP-address in BE-format
* 'src_port': senders UDP-port in BE-format
* 'src_mac_adr': senders MAC-address
* 'udp_sp_hd': UDP defined handle, identifying our SAP (i.e. port)
* 'length': length of received ethernet frame
* 'data': pointer for received ethernet frame (in driver's space)
*
*
* Return values :
* ---------------
* 'OK'
*
************************************************************************/
static
UINT32 NET_TFTPC_receive_data_block(
UINT32 src_ip_adr, /* IP BE-format */
UINT16 src_port, /* port BE-format */
t_mac_addr *src_mac_adr,/* MAC */
UINT32 udp_sp_hd, /* handle of open */
UINT32 length, /* total length */
UINT8 *data ) /* start of frame */
{
UINT32 rcode = OK ;
UINT8 *p ;
UINT16 opcode ;
UINT16 tmp2 ;
UINT32 tftp_data_length ;
int i, index ;
#ifdef NET_DEBUG
printf("NET_TFTPC_receive_data_block\n") ;
printf("src_ip_adr = %x\n", (unsigned)BE32_TO_CPU(src_ip_adr) ) ;
printf("src_port = %d\n", BE16_TO_CPU(src_port) ) ;
printf("length = %d\n", length ) ;
printf("src MAC = " ) ;
p = (UINT8*) src_mac_adr ;
for (i=0; i<6; i++)
{
printf(" %02x",*p++ ) ;
}
printf("\n" ) ;
#endif
/* We already registered an ERROR */
if (sap_context.sap_state == TFTPC_SAP_STATE_ERROR)
{
/* do nothing */
return(ERROR_NET_TFTPC_SAP_ERROR_STATE) ;
}
/* get TFTP-'opcode'-field of this received frame */
p = (data + TFTP_HEADER_BASE + TFTP_HEADER_OPCODE) ;
get2( p, opcode) ;
opcode = BE16_TO_CPU( opcode ) ;
get2( p, tmp2) ;
/* NOTE: 'tmp2' now keeps block-number or host-error */
tmp2 = BE16_TO_CPU( tmp2 ) ;
if (opcode != TFTP_HEADER_OPCODE_DATA)
{
/* We expect nothing else than 'DATA' or 'ERROR' */
/* check for HOST error */
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 /* There is no maximum file size, block numbers must wrap */
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 ) ;
}
/* Save data into user buffer */
tftp_data_length = length - (MAC_HEADER_SIZE + IP_HEADER_SIZE +
UDP_HEADER_SIZE + TFTP_HEADER_DATA) ;
if ( tftp_data_length <= sap_context.bytes_left )
{
/* we have space for this block */
/* OK, send ACK now */
sap_context.block_number = tmp2 ;
rcode = NET_TFTPC_sendACK( &sap_context ) ;
/* save data in user buffer */
memcpy( sap_context.puser,
&data[ TFTP_HEADER_BASE + TFTP_HEADER_DATA ],
tftp_data_length ) ;
/* update context */
sap_context.bytes_left = sap_context.bytes_left - tftp_data_length ;
sap_context.puser = sap_context.puser + tftp_data_length ;
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
{
/* New state: 'ERROR' */
sap_context.sap_state = TFTPC_SAP_STATE_ERROR ;
sap_context.error_cause = ERROR_NET_TFTP_FILE_TOO_BIG ;
rcode = ERROR_NET_TFTP_FILE_TOO_BIG ;
}
return( rcode ) ;
}
/************************************************************************
*
* NET_TFTPC_receive_data_byte
* Description :
* -------------
* This function is registered in the UDP-module and linked with a
* unique UDP-'port', idnetifying our SAP. This allows the UDP to call
* us back with an reference to the received frame,
* containing a TFTP-frame.
*
*
*
* Parameters :
* ------------
* 'src_ip_adr': senders IP-address in BE-format
* 'src_port': senders UDP-port in BE-format
* 'src_mac_adr': senders MAC-address
* 'udp_sp_hd': UDP defined handle, identifying our SAP (i.e. port)
* 'length': length of received ethernet frame
* 'data': pointer for received ethernet frame (in driver's space)
*
*
* Return values :
* ---------------
* 'OK'
*
************************************************************************/
static
UINT32 NET_TFTPC_receive_data_byte(
UINT32 src_ip_adr, /* IP BE-format */
UINT16 src_port, /* port BE-format */
t_mac_addr *src_mac_adr,/* MAC */
UINT32 udp_sp_hd, /* handle of open */
UINT32 length, /* total length */
UINT8 *data ) /* start of frame */
{
UINT32 rcode = OK ;
UINT8 *p ;
UINT16 opcode ;
UINT16 tmp2 ;
UINT32 tftp_data_length ;
int i, index ;
#ifdef NET_DEBUG
printf("NET_TFTPC_receive_data_byte\n") ;
printf("src_ip_adr = %x\n", (unsigned)BE32_TO_CPU(src_ip_adr) ) ;
printf("src_port = %d\n", BE16_TO_CPU(src_port) ) ;
printf("length = %d\n", length ) ;
printf("src MAC = " ) ;
p = (UINT8*) src_mac_adr ;
for (i=0; i<6; i++)
{
printf(" %02x",*p++ ) ;
}
printf("\n" ) ;
#endif
/* We already registered an ERROR */
if (sap_context.sap_state == TFTPC_SAP_STATE_ERROR)
{
/* do nothing */
return(ERROR_NET_TFTPC_SAP_ERROR_STATE) ;
}
/* get TFTP-'opcode'-field of this received frame */
p = (data + TFTP_HEADER_BASE + TFTP_HEADER_OPCODE) ;
get2( p, opcode) ;
opcode = BE16_TO_CPU( opcode ) ;
get2( p, tmp2) ;
/* NOTE: 'tmp2' now keeps block-number or host-error */
tmp2 = BE16_TO_CPU( tmp2 ) ;
if (opcode != TFTP_HEADER_OPCODE_DATA)
{
/* We expect nothing else than 'DATA' or 'ERROR' */
/* check for HOST error */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -