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

📄 net_udp.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************
 *
 *                          NET_UDP_close
 *  Description :
 *  -------------
 *  Close  UDP-SAP.
 *
 *
 *  Parameters :
 *  ------------
 *  -
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0),                UDP SAP has been closed
 *
 *
 ************************************************************************/
UINT32 NET_UDP_close( UINT32 sp_hd )
{
    /* validate handle */
    IF_UPPER( ERROR_NET_UDP_INVALID_HANDLE, sp_hd, UDP_SAP_COUNT)

    /* close SAP */
    sap_context[sp_hd].sap_state   = UDP_SAP_STATE_CLOSED ;
    sap_context[sp_hd].sap         = UDP_SAP_UNDEFINED ;
    sap_context[sp_hd].usr_receive = NULL ;

    return(OK) ;
}


/************************************************************************
 *
 *                          NET_UDP_send
 *  Description :
 *  -------------
 *  Request the UDP module to send a 'UDP' datagram
 *  to a specified destination IP-address and UDP-port.
 *
 *
 *  Parameters :
 *  ------------
 *  'ip_adr',           IN,   destination ip address (BE-format)
 *  'port',             IN,   destination udp port (BE-format)
 *  'mac_adr',          IN,   optional MAC address
 *  'sp_hd',            IN,   handle to select our SAP-context
 *  'length',           IN,   length of frame to send
 *  'data',             IN,   address to start of frame to be send
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'(=0)
 *
 ************************************************************************/
UINT32 NET_UDP_send( UINT32     ip_adr,   /* destination ip address (BE) */
                     UINT16     port,     /* port (BE-format)            */
                     t_mac_addr *mac_adr, /* optional MAC destination    */
                     UINT32     sp_hd,    /* handle returned of 'open'   */
                     UINT32     length,   /* total length of frame to send */
                     UINT8      *data  )  /* pointer to start of frame   */
{
    UINT32     rcode ;
    UINT8      *p ;
    UINT8      tmp1 ;
    UINT16     tmp2 ;
    UINT32     tmp4 ;
    int        i ;


    /* validate handle */
    IF_UPPER( ERROR_NET_UDP_INVALID_HANDLE, sp_hd, UDP_SAP_COUNT)

    /* Fill-in UDP header of frame */
    p = &data[UDP_HEADER_BASE + UDP_HEADER_SOURCE_PORT]  ;

    tmp2 = sap_context[sp_hd].sap ;
    put2( tmp2, p ) ;               /* Fill-in 'source_port'          */
    put2( port, p ) ;               /* Fill-in 'destination_port'     */

    tmp2 = CPU_TO_BE16(length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) ;
    put2( tmp2, p ) ;               /* Fill-in 'length'               */

    tmp2 = 0 ;
    put2( tmp2, p ) ;               /* Fill-in 'checksum' (temp = 0)  */

    /* Calculate UDP checksum, which include the pseudo header */

    /* get our IP address, and validate */
    IF_ERROR( (rcode),
              (SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
                            &(tmp4),
                            sizeof(tmp4)) ) )

    /* Fill-in the pseudo-header to prepare for checksum calculation */
    p = &data[UDP_PSEUDO_HEADER_BASE] ;
    put4( tmp4, p ) ;               /* Fill-in 'source-ip'           */
    put4( ip_adr, p ) ;             /* Fill-in 'dest-ip'             */
    tmp1 = 0 ;
    put1( tmp1, p ) ;               /* Fill-in 'zero'                */
    tmp1 = IP_SAP_UDP ;
    put1( tmp1, p ) ;               /* Fill-in 'protocol'            */
    tmp2 = CPU_TO_BE16(length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) ;
    put2( tmp2, p ) ;               /* Fill-in 'length'              */

    /* complete UDP-header with checksum */
    tmp2 = (UDP_PSEUDO_HEADER_SIZE + (length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)))/2 ;
    if (length%2)
    {
        data[length] = 0 ;
        tmp2 = tmp2 + 1 ;
    }

    p = &data[UDP_PSEUDO_HEADER_BASE] ;
    tmp2 = NET_checksum( (UINT16*)p, tmp2 ) ;
    if ( tmp2 == 0 )
    {
        tmp2 = ~tmp2 ;
    }
    p = (data + UDP_HEADER_BASE + UDP_HEADER_CHECKSUM) ;
    put2( tmp2, p ) ;               /* Fill-in calculated 'checksum'  */

    /* request IP to send this frame */
    rcode = NET_IP_send( ip_sp_hd,
                         ip_adr,  
                         mac_adr,
                         length,
                         data ) ;

    /* return completion */
    return( rcode ) ;
}



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


/************************************************************************
 *
 *                          NET_UDP_receive
 *  Description :
 *  -------------
 *  This function is registered in the IP-module and linked with the
 *  IP-protocol = '17', to let the IP call us back with a reference
 *  to the received frame, containing an UDP-frame.
 *  In this function the UDP-header will be validated and
 *  the any opened UDP-SAP will be checked to call a user registered
 *  receive handler.
 *
 *
 *
 *  Parameters :
 *  ------------
 *  'src_ip_adr':  sender's IP-address (BE-format)
 *  'src_mac_adr': sender's MAC-address
 *  'length':      length of received ethernet frame
 *  'data':        pointer for received ethernet frame (in driver's space)
 *
 *
 *  Return values :
 *  ---------------
 *  'OK'
 *
 ************************************************************************/
static
UINT32 NET_UDP_receive( UINT32     src_ip_adr,
                        t_mac_addr *src_mac_adr,
                        UINT32     length,
                        UINT8      *data    )
{
    UINT32            rcode ;
    UINT8             *p ;
    UINT8             tmp1 ;
    UINT16            tmp2, checksum, src_port, dst_port, udp_length ;
    UINT32            tmp4 ;
    t_udp_usr_receive receive ;
    int               i ;

#ifdef NET_DEBUG
    printf("NET_UDP_receive:\n") ;
#endif

    /* validate UDP checksum */
    p = (data + UDP_HEADER_BASE + UDP_HEADER_CHECKSUM) ;
    get2( p, checksum) ;

    /* Do checksum verification when requested */
    if (checksum != 0)
    {
        p = (data + UDP_HEADER_BASE + UDP_HEADER_CHECKSUM) ;
        tmp2 = 0 ;
        put2( tmp2, p ) ;

        /* prepend pseudo header */
        /* get our IP address, and validate */
        IF_ERROR( (rcode),
                  (SYSCON_read( SYSCON_COM_EN0_IP_ADDR_ID,
                                &(tmp4),
                                sizeof(tmp4)) ) )

        /* Fill-in the pseudo-header to prepare for checksum calculation */
        p = &data[UDP_PSEUDO_HEADER_BASE] ;
        put4( src_ip_adr, p ) ;       /* Fill-in 'source-ip'           */
        put4( tmp4, p ) ;             /* Fill-in 'dest-ip'             */
        tmp1 = 0 ;
        put1( tmp1, p ) ;               /* Fill-in 'zero'                */
        tmp1 = IP_SAP_UDP ;
        put1( tmp1, p ) ;               /* Fill-in 'protocol'            */
        tmp2 = CPU_TO_BE16(length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) ;
        put2( tmp2, p ) ;               /* Fill-in 'length'              */

        tmp2 = (UDP_PSEUDO_HEADER_SIZE + (length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)))/2 ;
        if (length%2)
        {
            data[length] = 0 ;
            tmp2 = tmp2 + 1 ;
        }

        p = &data[UDP_PSEUDO_HEADER_BASE] ;
        tmp2 = NET_checksum( (UINT16*)p, tmp2 ) ;
        if (tmp2 == 0)
        {
            tmp2 = ~tmp2 ;
        }
        if ( tmp2 != checksum )
        {
            return( ERROR_NET_UDP_INVALID_CHECKSUM ) ;
        }
    }

    /* validate UDP length */
    p = (data + UDP_HEADER_BASE + UDP_HEADER_LENGTH) ;
    get2( p, udp_length) ;
    udp_length = BE16_TO_CPU( udp_length ) ;
    if (udp_length != (length - (IP_HEADER_SIZE + MAC_HEADER_SIZE)) )
    {
        return( ERROR_NET_UDP_INVALID_LENGTH) ;
    }

    /* get UDP-'port'-field's of this received frame */
    p = (data + UDP_HEADER_BASE) ;
    get2( p, src_port) ;
    get2( p, dst_port) ;

    /* search SAP table to match any registered user */
    for ( i = 0; i <UDP_SAP_COUNT ; i++ )
    {
        if ( sap_context[i].sap == dst_port )
        {
            if ( sap_context[i].sap_state == UDP_SAP_STATE_OPEN )
            {
                /* we have a registered SAP context, call user */
                receive    = sap_context[i].usr_receive ;
                rcode = (*receive)( src_ip_adr,
                                    src_port,
                                    src_mac_adr,
                                    i,
                                    length,
                                    data ) ;
#ifdef NET_DEBUG
                if (rcode) printf("UDP-receive, rcode = %x\n", rcode ) ;
#endif
                return( rcode ) ;
            }
        }
    }
    return( ERROR_NET_UDP_NO_SAP ) ;
}

⌨️ 快捷键说明

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