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

📄 net_tftpc.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:

            /* 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 + -