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

📄 igmp_main.cpp

📁 igmp for switch in vxworks
💻 CPP
📖 第 1 页 / 共 5 页
字号:

	usCurrentMsgQLength = 0;
	usRealMaxMsgQLength = 0;

	usCurrentUser = 0;			/*当前组播用户数 */
	usCurrentGroup = 0;			/*当前频道数 */

	usCurrentTimer = 0;			/*当前定时器数 */

	unGeneralQueryTimerCount = 0;

	ucCurrentStartupQueryCount = 0;

	ulCustomMemoryUsed = 0;		/*当前内存块数 */

	bEnableInstantLeave = TRUE;
	bIgmpDebug = FALSE;

	pGroupEntityList = NULL;

	pPreJoinList = NULL;
	usCurrentPreJoinNode = 0;

	/*printf("%d Bytes per igmp group.\n",sizeof (GroupEntity)); */
	/*if (CreateMemory ((void *) IgmpGroupEntity, sizeof (GroupEntity),(usMaxGroup+1)) == NULL)
	   {
	   printf ("IGMP Create Group Memory FAIL!\n");
	   return FALSE;
	   }
	   else
	   {
	   printf("%d IgmpGroups Use %d KBytes Memory.\n",usMaxGroup,sizeof (GroupEntity)*(usMaxGroup+1)/(1024));
	   }

	   if (CreateMemory ((void *) IgmpTimerEntity, sizeof (TimerEntity),
	   usMaxTimer) == FALSE)
	   {
	   printf ("IGMP Create Timer Memory FAIL!\n");
	   return FALSE;
	   }
	   else
	   {
	   printf("%d IgmpTimers Use %d Bytes Memory.\n",usMaxTimer,sizeof (TimerEntity)*usMaxTimer);
	   } */

	tIgmpMembershipTimer = 0;
	StartIgmpMembershipTimer ();
	if (tIgmpMembershipTimer != 0)
	{
		/*printf("IGMP Memership Timer OK!\n"); */
	}
	if (bQuerierFlag)
	{
		RouterSendGenernalQueryToAllPort ();
		StartStartupQueryTimer ();
	}
	return TRUE;
}

/***************************************************
函数名称:ProcessReceiveIgmpPkt
函数功能:将接收到的数据包进行分类,交给其他模块处理。
输入参数:ReceiveIgmpMsg 接收到的数据包
返回值:	  无
***************************************************/
void ProcessReceiveIgmpPkt (IGMPMsg ReceiveIgmpMsg)
{
	if (slot_module[ReceiveIgmpMsg.usPort] == HOST_MODULE_PORT)	/*来自上联口侧 */
	{
		ulEtherReceiveIgmpPkt++;
		if (!bEnableHostModule)	/*Host功能被关闭 */
		{
			return;
		}

		switch (ReceiveIgmpMsg.ucIGMPType)
		{
			case IGMPMembershipQuery:
				if (ReceiveIgmpMsg.ucMaxResponseTime == 0)
				{
					ulEtherReceiveIgmpV1Query++;
					if (!bHostEnableIGMPV1)	/*不兼容V1 */
					{
						return;
					}
					HostProcessIgmpV1Query (ReceiveIgmpMsg);
				}
				else
				{
					ulEtherReceiveIgmpV2Query++;
					HostProcessIgmpV2Query (ReceiveIgmpMsg);
				}
				break;
			case IGMPV1MembershipReport:
				ulEtherReceiveIgmpV1MembershipReport++;
				if (!bHostEnableIGMPV1)	/*不兼容V1 */
				{
					return;
				}
				HostProcessIgmpReport (ReceiveIgmpMsg);
				break;
			case IGMPV2MembershipReport:
				ulEtherReceiveIgmpV2MembershipReport++;
				HostProcessIgmpReport (ReceiveIgmpMsg);
				break;
			case IGMPV3MembershipReport:
				ulEtherReceiveIgmpV3MembershipReport++;
				HostProcessIgmpReport (ReceiveIgmpMsg);
				break;
			case IGMPLeaveGroup:
				ulEtherReceiveIgmpLeaveGroup++;
				break;
			default:
				ulEtherReceiveIgmpUnknown++;
				break;
		}
	}

	else						/*来自router模块测 */
	{
		if (contest == TRUE)
		{
			if (ReceiveIgmpMsg.ucIGMPType == IGMPV2MembershipReport)
				processtest (ReceiveIgmpMsg.usPort, 1, 1, 1, 0,
					ReceiveIgmpMsg.unGroupAddress);
			else if (ReceiveIgmpMsg.ucIGMPType == IGMPLeaveGroup)
				processtest (ReceiveIgmpMsg.usPort, 1, 1, 0, 0,
					ReceiveIgmpMsg.unGroupAddress);
		}

		ulATMReceiveIgmpPkt++;
		if (!bEnableRouterModule)	/*Router功能关闭 */
		{
			ulATMReceiveIgmpBad++;

			if (bIgmpDebug)
			{
				printf ("Router is disable!Drop\n");
			}
			return;
		}

		if (!bEnablePortIGMP[ReceiveIgmpMsg.usPort])	/*该端口禁止组播功能 */
		{
			ulATMReceiveIgmpBad++;
			if (bIgmpDebug)
			{
				printf ("Port %d igmp is disable igmp!Drop\n",
					ReceiveIgmpMsg.usPort);
			}
			return;
		}

		usPortMapSessionId[ReceiveIgmpMsg.usPort] = ReceiveIgmpMsg.usSessionId;	/*保存SessionId */

		switch (ReceiveIgmpMsg.ucIGMPType)
		{
			case IGMPV2MembershipReport:
				ulATMReceiveIgmpV2MembershipReport++;
				semTake (semIgmpDelete, WAIT_FOREVER);
				RouterProcessIgmpV2Report (ReceiveIgmpMsg);
				semGive (semIgmpDelete);
				break;
			case IGMPV3MembershipReport:
				ulATMReceiveIgmpV3MembershipReport++;
				semTake (semIgmpDelete, WAIT_FOREVER);
				RouterProcessIgmpV2Report (ReceiveIgmpMsg);
				semGive (semIgmpDelete);
				break;
			case IGMPLeaveGroup:
				ulATMReceiveIgmpLeaveGroup++;
				semTake (semIgmpDelete, WAIT_FOREVER);
				RouterProcessIgmpLeave (ReceiveIgmpMsg);
				semGive (semIgmpDelete);
				break;
			case IGMPMembershipQuery:
				if (ReceiveIgmpMsg.ucMaxResponseTime == 0)
				{
					ulATMReceiveIgmpV1Query++;
					if (!bRouterEnableIGMPV1)	/*不兼容V1 */
					{
						return;
					}
					RouterProcessIgmpV1Query (ReceiveIgmpMsg);
				}
				else
				{
					ulATMReceiveIgmpV2Query++;
					RouterProcessIgmpV2Query (ReceiveIgmpMsg);
				}
				break;
			case IGMPV1MembershipReport:
				ulATMReceiveIgmpV1MembershipReport++;
				if (!bRouterEnableIGMPV1)	/*不兼容V1 */
				{
					return;
				}
				semTake (semIgmpDelete, WAIT_FOREVER);
				RouterProcessIgmpV1Report (ReceiveIgmpMsg);
				semGive (semIgmpDelete);
				break;
			default:
				ulATMReceiveIgmpUnknown++;
				break;
		}
	}
}

#ifdef __cplusplus
extern "C"
{
#endif

int send_igmp_packet_snooping (short srcPort, char *IgmpPkt, short usLength,
	short vlanid)
{
	char origin[70];
	char *p, *sendPkt;
	char type, iph_len;
	int i;
	short pvid = 0;

	/*get igmp type */
	  iph_len = (*(IgmpPkt + 14)) & 0xf;
	  type = *(IgmpPkt + 14 + 4 * iph_len);

	/*rebuild origin packet, if vlanid=4088, we think it's a untag packet, but there should be a bug hiding here: when 
	   the origin packet with tag 4088, it can transmitte to cpu, we can't know whether it has tag and so on */
	  memset (origin, 0, sizeof (origin));
	  pvid = driver_get_pvid (srcPort);
	if (vlanid != pvid)
	{
		memcpy (origin, IgmpPkt, 12);
		*(short *) (origin + 12) = htonl (0x8100);
		*(short *) (origin + 14) = htonl (vlanid);
		memcpy (origin + 16, IgmpPkt + 12, usLength - 12);
		sendPkt = origin;
	}
	else
	{
		sendPkt = IgmpPkt;
	}

	if (type == IGMPMembershipQuery)
	{
		/*错误的接收端口 */
		if (slot_module[srcPort] == ROUTER_MODULE_PORT)
			return -1;

		/*发往下行方向 */
		for (i = 1; i <= MAX_UPLINK_PORT; i++)
		{
			if (slot_module[i] == ROUTER_MODULE_PORT)
			{
				br_send_MSC (i, (u_char *) sendPkt, 70, 1);
			}
		}
	}

	/*往上联口发送的报文,加入 */
	else if (type == IGMPV2MembershipReport || type == IGMPLeaveGroup ||
		type == IGMPV1MembershipReport || type == IGMPV3MembershipReport)
	{
		/*错误的接收端口 */
		if (slot_module[srcPort] == HOST_MODULE_PORT)
			return -1;

		for (i = MIN_UPLINK_PORT; i <= MAX_UPLINK_PORT; i++)
		{
			if (slot_module[i] == HOST_MODULE_PORT)
			{
				br_send_MSC (i, (u_char *) sendPkt, 70, 1);
			}
		}
	}
	else
	{
		return -1;
	}

	if (bIgmpDebug)
	{
		printf ("\n\rsend IGMP packet type:%d  ", type);
		typePkt (sendPkt, 68);
	}

	return 0;
}

	int debug_igmp = 0;

/***************************************************
函数名称:IgmpReceive_new
函数功能:IGMP Proxy对外接口函数,负责将IGMP包送入消息队列
输入参数:usPort 接收数据包的源端口号
	 	 IgmpPkt 指向数据包的指针
	 	 usLength 数据包的长度
返回值:	 0  表示成功
	  	-1 表示失败
  备注:   将输入参数unPVC改为unPort ,这样可以去掉与pvc的转换过程   aibin  2005-01-14
***************************************************/
int IgmpReceive (USHORT usPort, char *IgmpRecPkt, USHORT usLength,
	short vlanid)
{
	IGMPMsg ReceiveIgmpMsg;
	ipheader *IpHeaderInPkt;
	igmpheader *IgmpHeaderInPkt;
	USHORT IpHeaderLength;
	UINT groupaddress;

	/*UINT DestinationAddressInPkt; */
	UCHAR IpProtocolInPkt;
	UINT MsgNum;
	int nReturnValue;
	UCHAR *user;			/*线卡上的用户端口aibin 2005-3-24 */
	USHORT usSessionId;
	char *p;
	char *p1;
	int *pp;
	int i;
	USHORT PPPoEFlag = 0;
	USHORT IGMPV3Flag = 0;

	/*USHORT usPort = TransformPVCToPort (unPVC);  modified by aibin 2005-01-14 */
	char IgmpPkt[200];

	/*edit by aibin 20080723 */
	memset (IgmpPkt, 0, sizeof (IgmpPkt));
	memcpy (IgmpPkt, IgmpRecPkt, usLength);

	if (debug_igmp)
		return 0;

	if (bIgmpDebug)
	{
		printf ("\n\rreceive IGMP from Slot %d, vlan %d", usPort, vlanid);
		typePkt (IgmpPkt, usLength);
	}
	/*协议报文来自自己发出的,丢弃 */
	if (memcmp (IgmpPkt + 6, (char *) gEtherInfo.etherMac, 6) == 0)
	{
		if (bIgmpDebug)
		{
			printf ("Error! Igmp Packet comes from myself!\r\n");
		}
		/*free ((void *) IgmpPkt);
		   /*device_driver_free ((void *) IgmpPkt); 
		   IgmpPkt = NULL; */
		return ERROR;
	}

	if (gIGMPMODE == MODE_SNOOPING)
	{
		send_igmp_packet_snooping (usPort, IgmpPkt, usLength, vlanid);
	}

/*
if (htonl (*((ULONG *) (IgmpPkt + 26))) == gEtherInfo.ipAddr)
{
	return ERROR;
}
*/

	timetick1 = tickGet ();
	if (*(IgmpPkt + 38) == 0x16)
	{
		timeget[groupid].tick1 = tickGet ();
	}

	ulIGMPReceivePktAll++;

/***********************************************************************************/

#if 1
	if (turbo)
	{
		groupaddress = htonl (*((ULONG *) (IgmpPkt + 42)));
		if (*(IgmpPkt + 38) == 0x16)
		{
			ulATMReceiveIgmpV2MembershipReport++;
			for (i = 0; i < MaxGroup; i++)
			{
				if (add[i].groupaddress == groupaddress)
				{
					if (add[i].slot[usPort])
					{
						return OK;
					}
					else
					{
						add[i].slot[usPort] = 1;
						add[i].count++;
						AddPortToGroup (groupaddress, usPort);
						timeget[groupid].tick4 = tickGet ();
						groupid++;
						return OK;
					}
				}
			}
			//printf("Rx Join\n");
			if (usCurrentGroup >= MaxGroup)
				return ERROR;
			usCurrentGroup++;
			AddGroup (groupaddress);
			timeget[groupid].tick2 = tickGet ();
			AddPortToGroup (groupaddress, usPort);
			SendIgmpPkt (IGMPV2MembershipReport, groupaddress, 0, 0);
			/*uESend((UINT *) IgmpPkt, usLength, 0, 0); */
			timeget[groupid].tick3 = tickGet ();
			timeget[groupid].groupaddress = groupaddress;
			i = 0;
			while (i < MaxGroup)
			{
				if (!add[i].groupaddress)
				{
					add[i].groupaddress = groupaddress;
					add[i].count++;
					add[i].slot[usPort] = 1;
					timeget[groupid].tick4 = tickGet ();
					groupid++;
					return OK;
				}
				i++;
			}
		}
		else if (*(IgmpPkt + 38) == 0x17)
		{
			ulATMReceiveIgmpLeaveGroup++;
			for (i = 0; i < MaxGroup; i++)
			{
				if (add[i].groupaddress == groupaddress)
				{
					if (add[i].slot[usPort])
					{
						DelPortFromGroup1 (groupaddress, usPort);
						add[i].slot[usPort] = 0;
						add[i].count--;
						if (!add[i].count)
						{
							DelGroup (groupaddress);

⌨️ 快捷键说明

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