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

📄 igmp.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
       sent here.  RFC 1112 specifies that membership in the all hosts group is
       never reported.
    */
    if (IP_Add_Multi(all_hosts_group, device) != NU_NULL)
        return NU_SUCCESS;
    else
        return NU_INVAL;

} /* IGMP_Initialize */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IGMP_Join                                                        
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      This function sends a multicast group membership report.  A timer
*      event is created to send a second copy of the report.            
*                                                                       
* INPUTS                                                                
*                                                                       
*      ipm         A pointer to the multicast group structure.          
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      None.                                                            
*                                                                       
*************************************************************************/
VOID IGMP_Join(IP_MULTI *ipm)
{

    /* Membership in the all hosts group is not reported. It is assumed that all
       level 2 conforming multicasts hosts are members of this group. */
    /* NOTE: When loop back of multicast packets is supported, membership should 
       not be reported in that case either. The interface should be checked here.
    */
    if (ipm->ipm_addr == LONGSWAP(IGMP_ALL_HOSTS_GROUP))
    {
        ipm->ipm_timer = 0;
    }
    else
    {
        /* Send a report of the membership.*/
        IGMP_Send(ipm);

        /* Set up timer event to send the report again just in case something 
           goes wrong with the first report. */
        ipm->ipm_timer = IGMP_Random_Delay(ipm);
    }

} /* IGMP_Join */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IGMP_Send                                                        
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Send an IGMP group membership report.                            
*                                                                       
* INPUTS                                                                
*                                                                       
*      ipm         A pointer to the multicast group structure.          
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      None.                                                            
*                                                                       
*************************************************************************/
VOID IGMP_Send(IP_MULTI *ipm)
{
    NET_BUFFER          *buf_ptr;
    IGMP_LAYER          *igmp;
    IP_MULTI_OPTIONS    mopt;
    STATUS              status;
    
    /* Allocate a buffer chain to build the IGMP report in. */
    buf_ptr = MEM_Buffer_Chain_Dequeue ( &MEM_Buffer_Freelist, 
                                         NET_MAX_IGMP_HEADER_SIZE);
    if (buf_ptr == NU_NULL)
        return;

    /* Initialize the size of the data in this buffer. */
    buf_ptr->mem_total_data_len = buf_ptr->data_len = sizeof (IGMP_LAYER);

    /* Set the deallocation list pointer. */
    buf_ptr->mem_dlist = &MEM_Buffer_Freelist;

    /* Point to the location within the buffer where the IGMP header will 
       be placed. */
    buf_ptr->data_ptr = buf_ptr->mem_parent_packet + NET_MAX_IP_HEADER_SIZE;

    /* Overlay the IGMP header. */
    igmp = (IGMP_LAYER *)buf_ptr->data_ptr;

    /* Initialize the IGMP header. */
    PUT8(igmp, IGMP_TYPE_OFFSET, IGMP_HOST_MEMBERSHIP_REPORT);
    PUT8(igmp, IGMP_UNUSED_OFFSET, 0);
    PUT32(igmp, IGMP_GROUP_OFFSET, ipm->ipm_addr);
    PUT16(igmp, IGMP_CKSUM_OFFSET, 0);
    PUT16(igmp, IGMP_CKSUM_OFFSET, TLS_IP_Check ((UINT16 *)igmp, sizeof(IGMP_LAYER)));

    /* Set up the multicast options that will be passed to the IP Layer. */
    UTL_Zero(&mopt, sizeof(mopt));
    mopt.ipo_device = ipm->ipm_device;
    mopt.ipo_ttl = 1;
    mopt.ipo_loop = 0;

    /* Send the IGMP report. */
    status = IP_Send(buf_ptr, NU_NULL, ipm->ipm_addr, *(UINT32 *)IP_Brd_Cast, 0, 
                        1, IP_IGMP_PROT, 0, &mopt);

    if (status != NU_SUCCESS)
    {
        /* The packet was not sent.  Dealocate the buffer.  If the packet was
           transmitted it will be deallocated later by TCP. */
        MEM_One_Buffer_Chain_Free (buf_ptr, &MEM_Buffer_Freelist);
    }
} /* IGMP_Send */

/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IGMP_Random_Delay                                                
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      Compute a "random" delay to be used for sending the next IGMP    
*      group membership report.                                         
*                                                                       
* INPUTS                                                                
*                                                                       
*      ipm         A pointer to the multicast group structure.          
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      UINT32      The length of time in ticks before the next report   
*                   should be sent.                                     
*                                                                       
*************************************************************************/
UINT32 IGMP_Random_Delay(IP_MULTI *ipm)
{
    UINT32 delay;

    /* Compute a "random" delay before an IGMP report will be sent. Base it on 
       the system clock + the group addr + the IP addr of the interface on which 
       the group was joined. The delay should be between 0 and 10 seconds. 1 
       tick is added to keep the delay from being zero. */
    delay = NU_Retrieve_Clock();
    delay += ipm->ipm_addr + ipm->ipm_device->dev_addr.dev_ip_addr;
    delay = (delay % (SCK_Ticks_Per_Second * 10)) + 1;

    UTL_Timerset (EV_IGMP_REPORT, (UINT32)ipm, delay, 0);
    
    return (delay);

} /* IGMP_Random_Delay */


/***********************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      IGMP_Leave                                                       
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*      This function kills any timer events that are pending when       
*      membership in a multicast group is dropped.                      
*                                                                       
* INPUTS                                                                
*                                                                       
*      ipm                             A pointer to the multicast group 
*                                       structure.                      
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      None.                                                            
*                                                                       
*************************************************************************/
VOID IGMP_Leave(IP_MULTI *ipm)
{
    /* If there is a timer event pending to send a group membership report, 
       clear the timer event. */
    if (ipm->ipm_timer)
    {
        ipm->ipm_timer = 0;
        UTL_Timerunset (EV_IGMP_REPORT, (UINT32)ipm, 1);
    }

}/* IGMP_Leave */

#endif /* INCLUDE_IP_MULTICASTING */

⌨️ 快捷键说明

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