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

📄 net_tftpc.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    printf("ipadr = %x\n", (unsigned)(BE32_TO_CPU(ipadr)) ) ;
    printf("filename = %s\n", filename ) ;
    printf("size = %d\n", *size ) ;
#endif

    /* clear error context */
    net_last_error  = OK ;
    net_diag_msg[0] = 0 ;

    if (*size > TFTP_FILE_MAX_SIZE)
    {
        rcode = ERROR_NET_TFTP_FILE_TOO_BIG ;
        net_last_error = rcode ;
        return( rcode ) ;
    }

    old_ie = sys_disable_int() ;
    switch (NET_TFTPC_state)
    {
        case TFTPC_STATE_CLOSED:
                rcode = ERROR_NET_TFTPC_NOT_INITIALIZED ;
            break;

        case TFTPC_STATE_OPEN:
                /* Reset the one and only SAP */
                rcode = NET_TFTPC_reset_sap( &sap_context,
                                             NET_TFTPC_receive_ack ) ;

                /* validate filename length */
                len = strlen(filename) ;
                if (len > TFTP_HEADER_FILENAME_MAX_LENGTH)
                {
                    rcode = ERROR_NET_TFTPC_INVALID_FILENAME ;
                    break;
                }

                /* Save user context to this SAP */
                sap_context.dst_ip_adr = ipadr ;
                sap_context.puser      = buffer ;
                sap_context.user_size  = *size ;
                sap_context.bytes_left = *size ;
                strcpy( sap_context.filename, filename ) ;
                strcpy( &sap_context.filename[len+1], TFTP_HEADER_MODE_OCTET ) ;

                /* Set retry count */
                sap_context.retry_left = TFTPC_SAP_MAX_RETRY_COUNT ;

                /* get time now (unit is seconds since 1.1.1970) */
                NET_gettime( &time_now ) ;
                sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ;

                /* New state = 'WAIT_FIRST_ACK' */
                sap_context.sap_state = TFTPC_SAP_STATE_WAIT_FIRST_ACK ;

                /* Send 'WRQ' */
                rcode = NET_TFTPC_sendWRQ( &sap_context ) ;
            break;

        default:
                /* we should never arrive here */
                rcode = ERROR_NET_TFTPC_FATAL_STATE ;
            break;

    }
    if(old_ie) sys_enable_int();

    while (1)
    {
        if ((rcode !=OK) && (rcode != ERROR_NET_ARP_MAC_NOT_RESOLUTED))
        {
            break ;
        }

        if ( sap_context.sap_state == TFTPC_SAP_STATE_LAST_BLOCK_WRITE )
        {
            rcode = OK ;
            break ;
        }

        if ( sap_context.sap_state == TFTPC_SAP_STATE_ERROR)
        {
            rcode = sap_context.error_cause ;
            break ;
        }

        (*poll)() ;
    }

    *size = sap_context.user_size - sap_context.bytes_left ;
    NET_TFTPC_close( 0 ) ;
    net_last_error = rcode ;
    return( rcode ) ;
}


/************************************************************************
 *
 *                          NET_TFTPC_poll
 *  Description :
 *  -------------
 *  Do timer managemnt of TFTPC-SAP's. or inquire state
 *
 *
 *  Parameters :
 *  ------------
 *  -
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0),
 *
 *
 ************************************************************************/
UINT32 NET_TFTPC_poll( UINT32 *state, UINT32 *last_io_compl, UINT32 *cause )
{
    UINT32 time_now ;
    UINT32 rcode, old_ie ;

    if ( sap_context.sap_state == TFTPC_SAP_STATE_BOUND_TO_UDP )
    {
        /* No TFTP-client session active; do nothing */
        return( OK ) ;
    }

    /* Check for inquire */
    if ( state != NULL )
    {
        old_ie = sys_disable_int() ;
        *state         = sap_context.sap_state ;
        *last_io_compl = sap_context.send_rc ;
        *cause         = sap_context.error_cause ;
        if(old_ie) sys_enable_int();
        return( OK ) ;
    }

    /* get time now (unit is seconds since 1.1.1970) */
    NET_gettime( &time_now ) ;

    old_ie = sys_disable_int() ;

    switch (sap_context.sap_state)
    {
        case TFTPC_SAP_STATE_WAIT_FIRST_BLOCK:
        {
            /* Check for 'RRQ' retry */
    
            if ( time_now >= sap_context.timeout )
            {
                /* Check for any retries */
                if (sap_context.retry_left)
                {
                    /* Send 'RRQ' */
                    sap_context.timeout = time_now + TFTPC_SAP_OPEN_TIMEOUT ;
                    sap_context.retry_left-- ;
                    rcode = NET_TFTPC_sendRRQ( &sap_context ) ;
                }
                else
                {
                    sap_context.sap_state   = TFTPC_SAP_STATE_ERROR ;
                    if (sap_context.send_rc == ERROR_NET_ARP_MAC_NOT_RESOLUTED)
                    {
                        sap_context.error_cause = ERROR_NET_ARP_TIME_OUT ;
                    }
                    else
                    {
                        sap_context.error_cause = ERROR_NET_TFTP_READ_TIMEOUT_ERROR ;
                    }
                }
            }
        }
        break ;


        case TFTPC_SAP_STATE_WAIT_FIRST_ACK:
        {
            /* Check for 'WRQ' retry */
    
            if ( time_now >= sap_context.timeout )
            {
                /* Check for any retries */
                if (sap_context.retry_left)
                {
                    /* Send 'WRQ' */
                    sap_context.timeout = time_now + TFTPC_SAP_OPEN_TIMEOUT ;
                    sap_context.retry_left-- ;
                    rcode = NET_TFTPC_sendWRQ( &sap_context ) ;
                }
                else
                {
                    sap_context.sap_state   = TFTPC_SAP_STATE_ERROR ;
                    if (sap_context.send_rc == ERROR_NET_ARP_MAC_NOT_RESOLUTED)
                    {
                        sap_context.error_cause = ERROR_NET_ARP_TIME_OUT ;
                    }
                    else
                    {
                        sap_context.error_cause = ERROR_NET_TFTP_WRITE_TIMEOUT_ERROR ;
                    }
                }
            }
        }
        break ;


        case TFTPC_SAP_STATE_WAIT_NEXT_BLOCK:
        {
            /* Check for 'ACK' retry */
    
            if ( time_now >= sap_context.timeout )
            {
                /* Check for any retries */
                if (sap_context.retry_left)
                {
                    /* Send 'ACK' */
                    sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ;
                    sap_context.retry_left-- ;
                    rcode = NET_TFTPC_sendACK( &sap_context ) ;
                }
                else
                {
                    sap_context.sap_state   = TFTPC_SAP_STATE_ERROR ;
                    sap_context.error_cause = ERROR_NET_TFTP_DATA_TIMEOUT_ERROR ;
                }
            }
        }
        break ;
    
        case TFTPC_SAP_STATE_WAIT_NEXT_ACK:
        {
            /* Check for 'DATA' retry */

            if ( time_now >= sap_context.timeout )
            {
                /* Check for any retries */
                if (sap_context.retry_left)
                {
                    /* Send 'DATA' */
                    sap_context.timeout = time_now + TFTPC_SAP_TIMEOUT ;
                    sap_context.retry_left-- ;
                    rcode = NET_TFTPC_sendDATA( &sap_context ) ;
                }
                else
                {
                    sap_context.sap_state   = TFTPC_SAP_STATE_ERROR ;
                    sap_context.error_cause = ERROR_NET_TFTP_DATA_TIMEOUT_ERROR ;
                }
            }
        }

        default:
                /* we should never arrive here */
            break;
    }

    if(old_ie) sys_enable_int();
    return( OK ) ;
}

/************************************************************************
 *      Implementation : Static functions
 ************************************************************************/


/************************************************************************
 *
 *                          NET_TFTPC_receive_ack
 *  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_ack( 
                          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 ;

    /* 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 ) ;

#ifdef NET_DEBUG
    printf("NET_TFTPC_receive_ack\n") ;
    printf("src_ip_adr = %x\n", (unsigned)BE32_TO_CPU(src_ip_adr) ) ;
    printf("src_port   = %d\n", (unsigned)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" ) ;
    printf("opcode     = %d\n", (unsigned)opcode) ;
    printf("block nr.  = %d\n", (unsigned)tmp2 ) ;
    printf("bytes_left = %d\n", (unsigned)sap_context.bytes_left ) ;
#endif

    if (opcode != TFTP_HEADER_OPCODE_ACK)
    {
        /* We expect nothing else than 'ACK' or 'ERROR' */

        /* check for HOST error */
        if (opcode == TFTP_HEADER_OPCODE_ERROR)
        {
            if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK)
            {
                /* 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_WRITE_ERROR ;
            }

            if ( (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_NEXT_ACK) ||
                 (sap_context.sap_state == TFTPC_SAP_STATE_LAST_BLOCK_WRITE) )
            {
                /* 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 ACK */
        return( sap_context.error_cause ) ;
    }


    /* We have 'ACK' */

    /* Check for 1. 'ACK' and save 'src_port', and src-MAC */
    if (sap_context.sap_state == TFTPC_SAP_STATE_WAIT_FIRST_ACK)
    {
        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,  */

⌨️ 快捷键说明

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