⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftpc.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
*   DESCRIPTION                                                           
*                                                                       
*       This function is responsible for sending an acknowledgement of   
*       a TFTP data packet.  The data is copied from the user's buffer   
*       into the TFTP CB send buffer.  This function also updates the    
*       pointer into the user's buffer and the number of bytes left      
*       to send in the buffer.                                           
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *tftp_con       The pointer to TFTP Control Block                
*                                                                       
*   OUTPUTS                                                              
*                                                                       
*       The Number of bytes sent on success.                             
*                                                                       
*************************************************************************/
INT32 TFTPC_Send_Data(TFTP_CB *tftp_con)
{
    UINT16 num_bytes;
    UINT32 bytes_read;
    
    /* Fill in the opcode and block number. */
    PUT16(tftp_con->trans_buf, 0, TFTP_DATA_OPCODE);
    PUT16(tftp_con->trans_buf, 2, tftp_con->block_number);
    
    /* Determine the number of bytes that will be sent in this packet - if
     * we have blksize or more bytes to send, we will send blksize bytes,
     * else, we will send the remainder of the file as our last packet
     */
    bytes_read = FAL_Fread(&(tftp_con->trans_buf[4]), tftp_con->options.blksize, 
        tftp_con->file_desc);
    
    if(bytes_read == tftp_con->options.blksize)
        num_bytes = tftp_con->options.blksize;
    else
        num_bytes = (UINT16)bytes_read;
    
    /* If we sent less than blksize bytes, we know it was the last packet */
    if (num_bytes < tftp_con->options.blksize)
        tftp_con->status = TRANSFER_COMPLETE;
    
    /* Send the data. */
    return (INT32)(NU_Send_To(tftp_con->socket_number,
        tftp_con->trans_buf, 
        (UINT16)(num_bytes + TFTP_HEADER_SIZE), 0,
        &tftp_con->server_addr, 0));
    
} /* end TFTPC_Send_Data */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Retransmit                                                 
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function will retransmit the last packet sent.              
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *tftp_con       The pointer to TFTP Control Block.
*       nbytes          The number of bytes to retransmit.                
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       The Number of bytes sent on success.                             
*                                                                       
*************************************************************************/
STATUS TFTPC_Retransmit(TFTP_CB *tftp_con, INT32 nbytes)
{
    return((INT)NU_Send_To(tftp_con->socket_number, tftp_con->trans_buf,
        (UINT16)nbytes, 0, &tftp_con->server_addr, 0));
}/* TFTPC_Retransmit */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Error                                                      
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function will send an error packet.                         
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *tftp_con       The pointer to TFTP Control Block.
*       error_code      The TFTP error code.         
*       *err_string     The error message to send.   
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       The Number of bytes sent on success.                             
*                                                                       
*************************************************************************/
STATUS TFTPC_Error(TFTP_CB *tftp_con, INT16 error_code, char *err_string)
{
    INT16         bytes_sent, send_size;
    
    /* Fill in the opcode and block number. */
    PUT16(tftp_con->trans_buf, 0, TFTP_ERROR_OPCODE);
    PUT16(tftp_con->trans_buf, 2, error_code);
    
    strcpy(&tftp_con->trans_buf[4], err_string);
    
    /* Size equals the length of the error string plus the null terminator. */
    send_size = (INT16)(strlen(err_string) + 1);
    
    /* Send the datagram. */
    bytes_sent = (INT16)(NU_Send_To(tftp_con->socket_number,
        tftp_con->trans_buf, 
        (UINT16)(send_size + TFTP_HEADER_SIZE),
        0, &tftp_con->server_addr, 0));
    
    return (bytes_sent);
} /* end TFTPC_Error */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Check_Options                                              
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function compares the options sent by the client with those 
*       returned from the server to be sure they are valid.              
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *tftp_con           The pointer to TFTP Control Block.
*       bytes_received      The bytes received in the OACK packet from the 
*                           server.
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       If the options are rejected, TFTP_BAD_OPTION,                    
*       If there is not tsize space available, TFTP_DISK_FULL            
*       Else, NU_SUCCESS                                                 
*                                                                       
*************************************************************************/
STATUS TFTPC_Check_Options(TFTP_CB *tftp_con, INT32 bytes_received)
{
    INT16   count = 2, count1;
    char    temp1[TFTP_PARSING_LENGTH];
    char    temp2[TFTP_PARSING_LENGTH];
    char    *op_holder;
    char    *value_holder;
    
    /* Set each acknowledgement field initially to false - we must track
     * acknowledged options only, and if an option was requested and
     * not acknowledged, we must reset its value to the default for
     * that option
     */
    tftp_con->options.timeout_acknowledged = NU_FALSE;
    tftp_con->options.blksize_acknowledged = NU_FALSE;
    tftp_con->options.tsize_acknowledged = NU_FALSE;
    
    /* Check if the server changed our requested option values */   
    while (count < bytes_received)
    {       
        count1 = 0;
        
        /* Parse the first option from the transmission buffer */
        while (tftp_con->trans_buf[count] != '\0')
        {
            temp1[count1] = tftp_con->trans_buf[count];
            count ++;
            count1 ++;
        }
        
        /* Null terminate temp1 */
        temp1[count1] = '\0';
        op_holder = (CHAR *)&temp1;
        
        count++;
        count1 = 0;
        
        /* Parse the first value from the transmission buffer */
        while (tftp_con->trans_buf[count] != '\0')
        {
            temp2[count1] = tftp_con->trans_buf[count];
            count ++;
            count1 ++;
        }
        
        /* Null terminate temp2 */
        temp2[count1] = '\0';
        value_holder = (CHAR *)&temp2;
        
        count++;
        
        /* The server has the authority to change the value of some
         * options we specified; check each returned option's value
         * and determine if any difference is valid
         */
        if (strcmp(op_holder, "timeout") == 0)
        {           
            /* The server may not change our timeout value */
            if ((UINT16)NU_ATOI(value_holder) != tftp_con->options.timeout)
                return(TFTP_BAD_OPTION);
            
            /* The server acknowledged our timeout option */
            tftp_con->options.timeout_acknowledged = NU_TRUE;
        }
        
        else if (strcmp(op_holder, "tsize") == 0)
        {
            /* If the file is bigger than we can hold, error */
            if ((UINT32)NU_ATOI(value_holder) > FAL_Disk_Space())
                return(TFTP_DISK_FULL);
            
            else
            {
                tftp_con->options.tsize = (UINT32)(NU_ATOI(value_holder));
                tftp_con->options.tsize_acknowledged = NU_TRUE;
            }
        }
        
        else if (strcmp(op_holder, "blksize") == 0)
        {   
            /* The server may not return a blksize larger than we
             * requested
             */
            if (((UINT16)NU_ATOI(value_holder) > tftp_con->options.blksize) ||
                ((UINT16)NU_ATOI(value_holder) == 0))
                return(TFTP_BAD_OPTION);
            
            /* The server may return a blksize smaller than we
             * requested; therefore, set our blksize to that value
             */
            else if ((UINT16)NU_ATOI(value_holder) < tftp_con->options.blksize)
                tftp_con->options.blksize = (UINT16)(NU_ATOI(value_holder));
            
            /* The server acknowledged our blksize option */
            tftp_con->options.blksize_acknowledged = NU_TRUE;
        }
        
        /* Otherwise, the server is sending us unsupported options */
        else
            TFTPC_Error(tftp_con, 8, "Error: Option Not Supported. ");
    }
    
    /* We may use only those options that the server acknowledges - if
     * the server did not acknowledge an option, set it back to the default
     */
    if (tftp_con->options.timeout_acknowledged != NU_TRUE)
        tftp_con->options.timeout = TFTP_TIMEOUT_DEFAULT;
    
    if (tftp_con->options.blksize_acknowledged != NU_TRUE)
        tftp_con->options.blksize = TFTP_BLOCK_SIZE_DEFAULT;
    
    return(NU_SUCCESS);
}

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Set_Options                                                
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function verifies the validity of the blksize and timeout   
*       options requested - if they are invalid, it sets them to the     
*       valid defaults.                                                  
*                                                                       
*   INPUTS                                                                
*                                                                       
*       buf_size        Size of the user buffer.                         
*       *ops            Pointer to the options structure.
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                                                       
*                                                                       
*************************************************************************/
STATUS TFTPC_Set_Options(UINT32 buf_size, TFTP_OPTIONS *ops)
{
    /* If the user did not specify a blksize, set it to the default
     * Also, if the user passes in a value larger than a UINT16 for
     * blksize, sets blksize to default.  Or, if the user specifies a
     * value larger than the max, set it to the default
     */
    if ((ops->blksize < TFTP_BLOCK_SIZE_MIN) || 
        (ops->blksize > TFTP_BLOCK_SIZE_MAX))
        ops->blksize = TFTP_BLOCK_SIZE_DEFAULT;
    
    /* If the blksize is greater than the transmission size, set it
     * to the blksize - it is wasteful to allocate more memory for a
     * transmission buffer than we need
     */
    if ((ops->blksize > buf_size) && (buf_size != 0))
        ops->blksize = (UINT16)buf_size;
    
    /* Per RFC 2349, the timeout interval must be between 1 and 255 - if
     * the timeout is 0, then the user did not specify a timeout, and we
     * want the server to use its default and we will use our default;
     * therefore, leave it 0 for now.
     */
    if (ops->timeout > 255)
        ops->timeout = TFTP_TIMEOUT_DEFAULT;    
    
    return (NU_SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -