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

📄 net_tftpc.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -