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

📄 net.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* Verify that the device is up. */
    if ( (device->dev_flags & (DV_UP | DV_RUNNING)) != (DV_UP | DV_RUNNING) )
        return (NU_HOST_UNREACHABLE);

    if (ro)
        rt = ro->rt_route;

    /* Verify the route is up. Both gwroute and rt are set equal to the route
       located by IP_Send. */
    if(rt)
    {
        /* If the route is not up then try to locate an alternate route. */
        if ((rt->rt_flags & RT_UP) == 0)
        {
            if ( (rt = RTAB_Find_Route(dest)) != NU_NULL)
                rt->rt_refcnt--;
            else
                return (NU_HOST_UNREACHABLE);
        }
    }

    switch(dest->sck_family)
    {
        case SK_FAM_IP:

            /* Resolve the MAC address. */
            if (ARP_Resolve(device, dest, mac_dest, buf_ptr) != NU_SUCCESS)
                
                /* To the upper layer protocols this is the same as a 
                   successful send. */
                return NU_SUCCESS;

            type = EIP;

            break;


        case SK_FAM_UNSPEC:
            /* Family is unspecified.  This should be an ARP packet. */

            /* Point to the ethernet header information, and extract the type
               and destination address. */
            eh = (ARP_MAC_HEADER *)dest;
            memcpy (mac_dest, eh->ar_mac.ar_mac_ether.dest, DADDLEN);
            type = eh->ar_mac.ar_mac_ether.type;

            break;

        default:
            return -1;

    }

    /* Move back the data pointer to make room for the MAC layer and adjust the 
       packet length. */
    buf_ptr->data_ptr           -= device->dev_hdrlen;
    buf_ptr->data_len           += device->dev_hdrlen;
    buf_ptr->mem_total_data_len += device->dev_hdrlen;

    /* Initialize the ethernet header. */
    PUT16(buf_ptr->data_ptr, ETHER_TYPE_OFFSET, type);
    PUT_STRING(buf_ptr->data_ptr, ETHER_DEST_OFFSET, mac_dest, DADDLEN);
    PUT_STRING(buf_ptr->data_ptr, ETHER_ME_OFFSET, device->dev_mac_addr, DADDLEN);

#if (INCLUDE_SNMP == NU_TRUE)
    /* Is this a unicast or a non-unicast packet. */
    if ( (buf_ptr->mem_flags & NET_BCAST) || (buf_ptr->mem_flags & NET_MCAST) )
        SNMP_ifOutNUcastPkts_Inc(device->dev_index);
    else
        SNMP_ifOutUcastPkts_Inc(device->dev_index);
#endif


#ifdef PACKET

    /* Pass the packet to the device. */
    device->dev_start(device, buf_ptr);

    /* The packet has been transmitted.  Deallocate the buffer. */
    MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);
#else

    old_int = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);

    /* Place the buffer on the device's transmit queue. */
    MEM_Buffer_Enqueue(&device->dev_transq, buf_ptr);

    ++device->dev_transq_length;

    /* SPR #0541 */
    /* Increment the number of packet on the out going Q */
    SNMP_ifOutQLen_Inc(device->dev_index);

    /* If this is the first buffer in the transmit queue we need to resume the
     * transmit task.  If not another packet is already being transmitted. */
    if(device->dev_transq.head == buf_ptr)    
    {
        NU_Local_Control_Interrupts(old_int);

        /* Resume the the transmit task. */
        device->dev_start(device, buf_ptr);
    }
    else
        NU_Local_Control_Interrupts(old_int);

#endif

    return(NU_SUCCESS);

}  /* NET_Ether_Send */

/*************************************************************************
*                                                                         
*   FUNCTION                                                              
*                                                                         
*       NET_Add_Multi                                                     
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       When an ethernet multicast group is joined this function adds an 
*       entry to the list of ethernet multicast addresses a device should 
*       receive.  If the specified address is already registered with the 
*       device the reference count is incremented.                        
*                                                                         
*   INPUTS                                                                
*                                                                         
*       *dev                                                              
*       *d_req                                                            
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       NU_SUCCESS                                                        
*       NU_MEM_ALLOC                                                      
*       NU_RESET                                                          
*       -1                                                                
*                                                                         
*************************************************************************/
STATUS NET_Add_Multi(DV_DEVICE_ENTRY *dev, DV_REQ *d_req)
{
    UINT8       multi_addr[6];
    INT         irq_level;
    NET_MULTI   *em;
    UINT8       temp[4];

    irq_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);

    PUT32(temp, 0, LONGSWAP(d_req->dvr_addr));

    /* Convert the IP address to a multicast ethernet address. */
    NET_MAP_IP_TO_ETHER_MULTI(temp, multi_addr);

    /* Verify that the ethernet multicast address is valid. */
    if (((multi_addr[0] & 0xFF) != 1) || ((multi_addr[2] & 0xFF) != 0x5e))
    {
        NU_Local_Control_Interrupts(irq_level);
        return (-1);
    }

    /* Has this address already been added to the list. */
    for ( em = dev->dev_ethermulti;
          em != NU_NULL && (memcmp(em->nm_addr, multi_addr, 6) != 0);
          em = em->nm_next);

    if(em != NU_NULL)
    {
        /* Found a match. Increment the reference count. */
        em->nm_refcount++;
        NU_Local_Control_Interrupts(irq_level);
        return (NU_SUCCESS);
    }

    /* This is a new address. Allocate some memory for it. */
    if (NU_Allocate_Memory(&System_Memory, (VOID **)&em,
                            sizeof (*em), (UNSIGNED)NU_NO_SUSPEND) != NU_SUCCESS)
    {
        NU_Local_Control_Interrupts(irq_level);
        return(NU_MEM_ALLOC);
    }

    /* Initialize the new entry. */
    memcpy(em->nm_addr, multi_addr, 6);
    em->nm_device = dev;
    em->nm_refcount = 1;

    /* Link it into the list. */
    em->nm_next = dev->dev_ethermulti;
    dev->dev_ethermulti = em;

    /*  Restore the previous interrupt lockout level.  */
    NU_Local_Control_Interrupts(irq_level);

    return(NU_RESET);

} /* NET_Add_Multi */

/*************************************************************************
*                                                                         
*   FUNCTION                                                              
*                                                                         
*       NET_Del_Multi                                                     
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       When an ethernet multicast group is dropped this function will 
*       delete the entry from the list of ethernet multicast addresses 
*       this device should receive if the refernce count drops to 0.  
*       Else the reference count is decremented.                          
*                                                                         
*   INPUTS                                                                
*                                                                         
*       *dev                                                              
*       *d_req                                                            
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       NU_SUCCESS                                                        
*       NU_INVAL                                                          
*       NU_RESET                                                          
*       -1                                                                
*                                                                         
*************************************************************************/
STATUS NET_Del_Multi(DV_DEVICE_ENTRY *dev, DV_REQ *d_req)
{
    UINT8       multi_addr[6];
    INT         irq_level;
    NET_MULTI   *em;
    NET_MULTI   **ptr;
    UINT8               temp[4];

    irq_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);

    PUT32(temp, 0, LONGSWAP(d_req->dvr_addr));

    /* Convert the IP address to a multicast ethernet address. */
    NET_MAP_IP_TO_ETHER_MULTI(temp, multi_addr);

    /* Verify that the ethernet multicast address is valid. */
    if (((multi_addr[0] & 0xFF) != 1) || ((multi_addr[2] & 0xFF) != 0x5e))
    {
        NU_Local_Control_Interrupts(irq_level);
        return (-1);
    }

    /* Find this address in the list. */
    for ( em = dev->dev_ethermulti;
          em != NU_NULL && (memcmp(em->nm_addr, multi_addr, 6) != 0);
          em = em->nm_next);

    if(em == NU_NULL)
    {
        /* Found a match. Increment the reference count. */
        NU_Local_Control_Interrupts(irq_level);
        return (NU_INVAL);
    }

    /* If this is not the last refernce then return after decremanting the 
       reference count. */
    if (--em->nm_refcount != 0)
    {
        NU_Local_Control_Interrupts(irq_level);
        return(NU_SUCCESS);
    }

    /* If we made this far then there are no more references to this entry.
       So unlink and deallocte it. */
    for ( ptr = &em->nm_device->dev_ethermulti;
          *ptr != em;
          ptr = &(*ptr)->nm_next)
        continue;

    *ptr = (*ptr)->nm_next;

    /*  Restore the previous interrupt lockout level.  */
    NU_Local_Control_Interrupts(irq_level);

    /* Deallocate the structure. */
    NU_Deallocate_Memory(em);

    return(NU_RESET);

} /* NET_Del_Multi */

⌨️ 快捷键说明

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