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

📄 udp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:

        return (stat);
    }

    /*  If the send went ok, then return the number of bytes sent. */
    return(nbytes);

}  /* UDP_Send */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       UDP_Cache_Route                                                  
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Cache a route for a UDP socket.                                  
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *uprt                                                            
*       ip_addr                                                          
*                                                                       
*   OUPUTS                                                                
*                                                                       
*       NU_SUCCESS                                                       
*       NU_HOST_UNREACHABLE                                              
*                                                                       
*************************************************************************/
STATUS UDP_Cache_Route (UDP_PORT *uprt, UINT32 ip_addr)
{
    RTAB_ROUTE      *ro;
    UINT32          search_addr = ip_addr;

    /* Point to the cached route */
    ro = &uprt->up_route;

    /* If the destination is the limited broadcast address, update it to the
       broadcast address for the primary network interface. This is for the 
       purposes of route discovery below. */
    if (search_addr == IP_ADDR_BROADCAST)
    {
        /* default bcast route? */
        if ( (uprt->up_socketd >= 0) && 
             (SCK_Sockets[uprt->up_socketd]->s_bcast_if) )

            /* Set the search addr */
            search_addr = SCK_Sockets[uprt->up_socketd]->
                                s_bcast_if->dev_addr.dev_net;
        else
        {
            /* Use the primary interface, skip the loopback */
            if ( (DEV_Table.dv_head->dev_type == DVT_LOOP) && 
                 (DEV_Table.dv_head->dev_next != NU_NULL) )
                search_addr = DEV_Table.dv_head->dev_next->dev_addr.dev_net;
            else
                search_addr = DEV_Table.dv_head->dev_addr.dev_net;
        }

        /* Free the cached route. The default IF for sending a
           bcast packet may have change. */
        if (ro->rt_route)
        {
            RTAB_Free(ro->rt_route);
            ro->rt_route = NU_NULL;
        }
                
    }
    
    /* If this is a multicast address then check for a default route. */
    else if (IP_MULTICAST_ADDR(search_addr))
    {
        /* default mcast route? */
        if ( (uprt->up_socketd >= 0) && 
             (SCK_Sockets[uprt->up_socketd]->s_moptions) &&
             (SCK_Sockets[uprt->up_socketd]->s_moptions->ipo_device) )
        {
            /* Set the search addr */
            search_addr = SCK_Sockets[uprt->up_socketd]->
                          s_moptions->ipo_device->dev_addr.dev_net;

            /* Is there a cached route? */
            if (ro->rt_route)
            {

                /* Check the IF used by the cached route. If it is different
                   than the set default IF free it so a new route can be found. */
                if (SCK_Sockets[uprt->up_socketd]->s_moptions->ipo_device !=
                    ro->rt_route->rt_device)
                {
                    RTAB_Free(ro->rt_route);
                    ro->rt_route = NU_NULL;
                }
            }
        }
    }
        
    /* If there is already a route cached but the destination IP addresses 
       don't match then free the route. This comparison is done to the real 
       IP address not the search address, they will only be different when a 
       route for the limited broadcast address is desired. */
    if  (ro->rt_route && ((ro->rt_ip_dest.sck_addr != ip_addr) || 
        ((!(ro->rt_route->rt_device->dev_flags & DV_RUNNING)) &&
        (!(ro->rt_route->rt_device->dev_flags & DV_UP)))))
    {
        RTAB_Free(ro->rt_route);
        ro->rt_route = NU_NULL;
    }

    /* If there is no cached route then try to find one. */
    if ( ro->rt_route == NU_NULL )
    {
        ro->rt_ip_dest.sck_addr = search_addr;
        ro->rt_ip_dest.sck_family = SK_FAM_IP;
        IP_Find_Route(ro);
    }

    /* If no route was found and this is a multicast address then 
       just use the primary interface. */
    if ( (!ro->rt_route) && (IP_MULTICAST_ADDR(search_addr)) )
    {
        if ( (DEV_Table.dv_head->dev_type == DVT_LOOP) && 
             (DEV_Table.dv_head->dev_next != NU_NULL) )
            ro->rt_ip_dest.sck_addr = DEV_Table.dv_head->dev_next->dev_addr.
                                                            dev_net_brdcast;
        else
            ro->rt_ip_dest.sck_addr = DEV_Table.dv_head->dev_addr.
                                                                dev_net_brdcast;

        IP_Find_Route(ro);            
            
    }

    /* If it was the limited broadcast address (255.255.255.255) or a
       multicast address that a route was desired for then the route 
       address will be wrong. Go ahead and update it for all cases.
    */
    ro->rt_ip_dest.sck_addr = ip_addr;
    
    if (ro->rt_route)
    {
        return NU_SUCCESS;
    }
    else
        return (NU_HOST_UNREACHABLE);

} /* UDP_Cache_Route */

/*************************************************************************
*
*   FUNCTION
*
*       UDP_Port_Cleanup
*
*   DESCRIPTION
*
*       This function frees any resources associate with a UDP port when
*       that port is closed.
*
*   INPUTS
*
*       uport_index                   The index of the port that is closing.
*
*   OUTPUTS
*
*       NU_SUCCESS
*
*************************************************************************/
STATUS UDP_Port_Cleanup(INT uport_index)
{

    /*  Clear this port list entry.  */
    NU_Deallocate_Memory((VOID *) UDP_Ports[uport_index]);

    /*  Indicate that this port is no longer used. */
    UDP_Ports[uport_index] = NU_NULL;

    return (NU_SUCCESS);

} /* UDP_Port_Cleanup */

/*************************************************************************
*                                                                       
*   FUNCTION                                                             
*                                                                       
*       UDP_Make_Port                                                    
*                                                                       
*   DESCRIPTION                                                          
*                                                                       
*       This is the intialization for UDP based communication.  When a 
*       port needs to be created, this routine is called to do as much 
*       pre-initialization as possible to save overhead during operation.
*                                                                       
*       This structure is created upon open of a port, either listening 
*       or wanting to send.                                              
*                                                                       
*   INPUTS                                                               
*                                                                       
*       myport                                                           
*       socketd                                                          
*                                                                       
*   OUTPUTS                                                              
*                                                                       
*       INT16                                                            
*                                                                       
*************************************************************************/
INT16 UDP_Make_Port (UINT16 myport, INT socketd)
{
    INT16 i, retval;
    UDP_PORT *p;
    STATUS  status;
    VOID    *return_ptr;       /* pointer to memory block */

#if (INCLUDE_SNMP == NU_TRUE)
   struct sock_struct       *sockptr;
   sockptr = SCK_Sockets[socketd];
#endif

    /* Check to see if there are any available ports. */
    for ( i = 0; (UDP_Ports[i] != NU_NULL) && (i < UDP_MAX_PORTS); i++);

    /* If an unused UDP port was not found return an error. */
    if (i >= UDP_MAX_PORTS)
    {
        NERRS_Log_Error ( NERR_RECOVERABLE, __FILE__, __LINE__);
        retval = -1;
    }
    else
    {
        status = NU_Allocate_Memory(&System_Memory, (VOID **) &return_ptr,
                                (UNSIGNED)sizeof(struct uport),
                                (UNSIGNED)NU_NO_SUSPEND);

        /* check status of memory allocation */
        if (status == NU_SUCCESS)
        {
            return_ptr = (UINT16 *)TLS_Normalize_Ptr(return_ptr);
            p = (UDP_PORT *)return_ptr;
        }
        else
        {
            /* ERROR memory allocation error. */
            NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
            return (-1);               /* out of room for ports */
        } /* end if */

        UDP_Ports[i] = p;
        retval = i;

        /* Clear the UDP port structure. */
        UTL_Zero((CHAR *)p, sizeof(*p));

        /* If my port number has not been specified then find a unique one
           for me. */
        if (myport == 0)
            /* Build a local port number.  Needs to be unique and greater than
               2048.  */
            myport = UTL_Get_Unique_Port_Number();

        p->up_lport = myport;                   /* save for incoming comparison */

        /* The socket with which this port is associated is unkown at this time. */
        p->up_socketd = socketd;

        p->up_route.rt_route = NU_NULL;

#if (INCLUDE_SNMP == NU_TRUE)
        /* Update the UDP Listen Table. */
        SNMP_udpListenTableUpdate(SNMP_ADD, sockptr->s_local_addr.ip_num.is_ip_addrs, 
                                  (UNSIGNED)myport);
#endif
    }

    return (retval);

}  /* end UDP_Make_Port() */


#endif /* INCLUDE_UDP == NU_TRUE */

⌨️ 快捷键说明

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