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

📄 igmp_main.cpp~

📁 igmp for switch in vxworks
💻 CPP~
📖 第 1 页 / 共 5 页
字号:
	ulIGMPV2MembershipReportSent = 0;	/*统计发送版本2报告的总数 */
	ulIGMPLeaveGroupSent = 0;	/*统计发送离开包的总数 */
	ulIGMPEtherSent = 0;		/*统计Ether发送的包总数 */

	ulGeneralQueryTimeOutTimes = 0;
	ulHostReportDelayTimeOutTimes = 0;
	ulGroupPortV2MembershipTimeOutTimes = 0;
	ulGroupPortLastMemberQueryTimeOutTimes = 0;
	ulGroupV1HostPresentTimeOutTimes = 0;
	ulGroupPortV1HostTimeOutTimes = 0;
	ulStartupQueryTimeOutTimes = 0;
	ulV1RouterPresentTimeOutTimes = 0;
	ulOtherQuerierPresentTimeOutTimes = 0;

	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");
			}
			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++;

⌨️ 快捷键说明

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