📄 igmp.c
字号:
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 + -