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

📄 igmp_router.cpp

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

/*******************************************************
文件名: igmp_router.cpp
文件说明:
本文件是IGMP Router子模块文件,负责处理来自ATM的IGMP
包,完成IGMP Router功能。

修改记录:

1. 2004-4-7 changzhan 初次建立本文件
*******************************************************/

/*
#include "igmp.h"
#include "igmp_interface.h"
#include <ipuplink.h>

#include <CustomMemory.h>
#include <CustomTimer.h>
#include "Igmp_control.h"
*/
#include "igmpcon.h"
#define ROUTER_VID 4088
#define HOST_VID 4088
#define ReservedVlan 4089
#define DefaultVlan 4088

/***************************************************
函数名称:RouterProcessIgmpV2Query
函数功能:处理IGMP V1查询包
输入参数:ReceiveIgmpMsg 接收到的IGMP包 
返回值:	 无
***************************************************/

struct ethernet_information gEtherInfo1;	/*aibin */
void RouterProcessIgmpV1Query (IGMPMsg ReceiveIgmpMsg)
{
	if (!bEnableQueryElection)
	{
		return;
	}
}

/***************************************************
函数名称:RouterProcessIgmpV2Query
函数功能:处理IGMP V2查询包
输入参数:ReceiveIgmpMsg 接收到的IGMP包 
返回值:	 无
***************************************************/
void RouterProcessIgmpV2Query (IGMPMsg ReceiveIgmpMsg)
{
	GroupEntity *pTemp;
	int i;						/*,Flag = 0 */

	if (!bEnableQueryElection)
	{
		return;
	}

	pTemp = pGroupEntityList;
	while (pTemp)
	{
		for (i = 1; i <= MAX_UPLINK_PORT; i++)
		{
			if (pTemp->eGroupPortStatus[i] == CheckingMembership)
			{
				/*Flag = 1; */
				return;
			}
		}
		pTemp = pTemp->pNext;
	}

	/*if(Flag == 1) 有成员正在离开,忽略查询消息
	   {
	   return;
	   }  2004.11.9 */

	if (gEtherInfo.ipAddr > ReceiveIgmpMsg.unSourceAddress)
	{
		bQuerierFlag = FALSE;
		StartOtherQuerierPresentTimer ();
		/*if (tGeneralQueryTimer != 0)
		   {
		   StopGeneralQueryTimer ();
		   } */
		if (tStartupQueryTimer != 0)
		{
			StopStartupQueryTimer ();
		}
	}
}

/***************************************************
函数名称:RouterProcessIgmpV1Report
函数功能:处理IGMP V1 Report包
输入参数:ReceiveIgmpMsg 接收到的IGMP包 
返回值:	 无
***************************************************/
void RouterProcessIgmpV1Report (IGMPMsg ReceiveIgmpMsg)
{
	GroupEntity *IgmpGroup;

	if ((ReceiveIgmpMsg.unDestinationAddress != ReceiveIgmpMsg.unGroupAddress))
	{							/*数据包非法则丢弃 */
		ulATMReceiveIgmpBad++;
		if (bIgmpDebug)
		{
			printf ("RouterProcessIgmpV1Report Receive Bad Pkt!\n");
		}
		return;
	}

	IgmpGroup = FindIgmpGroupByAddress (ReceiveIgmpMsg.unGroupAddress);
	if (IgmpGroup == NULL)		/*组播组不存在 */
	{
		if ((usCurrentUser >= usMaxUser) || (usCurrentGroup > MaxGroup))
		{						/*达到容量限制 */
			return;
		}
		IgmpGroup = AddNewIgmpGroup (ReceiveIgmpMsg.unGroupAddress);
		IgmpGroup->OutVlanTag = GetGroupVlan (ReceiveIgmpMsg.unGroupAddress);
		if (IgmpGroup == NULL)	/*添加组播组失败 */
		{
			printf ("AddNewIgmpGroup FAIL!\n");
			return;
		}
		semTake (semIgmpDelete, WAIT_FOREVER);
		AddPortToSpecificGroup (ReceiveIgmpMsg.unGroupAddress,
			ReceiveIgmpMsg.usPort);
		StartGroupPortV2MembershipTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
		IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] = V1MembersPresent;

		IgmpGroup->bGroupV1HostPresentFlag = TRUE;
		if (!IfPreJoinNodeExist (ReceiveIgmpMsg.unGroupAddress))	/*如果不是预加入的组就发加入报文 2006.8.8 */
			SpecificGroupSendV1Report (ReceiveIgmpMsg.unGroupAddress);
		StartHostReportDelayTimer (IgmpGroup, usUnsolicitedReportInterval);

		StartGroupV1HostPresentTimer (IgmpGroup);
		StartGroupPortV1HostTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
		AddPortToSearchGroup (IgmpGroup, ReceiveIgmpMsg.usPort);

		usCurrentUser++;
		semGive (semIgmpDelete);

	}
	else						/*组播组已经存在 */
	{
		if (!FindPortInSpecificGroup (IgmpGroup, ReceiveIgmpMsg.usPort))	/*端口不存在 */
		{
			if (usCurrentUser >= usMaxUser)
			{					/*达到容量限制 */
				return;
			}
			semTake (semIgmpDelete, WAIT_FOREVER);
			AddPortToSpecificGroup (ReceiveIgmpMsg.unGroupAddress,
				ReceiveIgmpMsg.usPort);
			IgmpGroup->bGroupV1HostPresentFlag = TRUE;
			IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] =
				V1MembersPresent;

			IgmpGroup->usGroupUserNumber++;	/*组成员数加1 */

			StartGroupPortV2MembershipTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
			StartGroupV1HostPresentTimer (IgmpGroup);

			StartGroupPortV1HostTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
			AddPortToSearchGroup (IgmpGroup, ReceiveIgmpMsg.usPort);
			AddPortToGroup (ReceiveIgmpMsg.unGroupAddress,
				ReceiveIgmpMsg.usPort);
			usCurrentUser++;
			semGive (semIgmpDelete);
		}
		else					/*端口已经存在 */
		{
			IgmpGroup->bGroupV1HostPresentFlag = TRUE;
			IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] =
				V1MembersPresent;

			StartGroupPortV2MembershipTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
			StartGroupV1HostPresentTimer (IgmpGroup);
			StartGroupPortV1HostTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
		}
	}
}

/***************************************************
函数名称:RouterProcessIgmpV2Report
函数功能:处理IGMP V2 Report包
输入参数:ReceiveIgmpMsg 接收到的IGMP包 
返回值:	 无
***************************************************/
void RouterProcessIgmpV2Report (IGMPMsg ReceiveIgmpMsg)
{
	GroupEntity *IgmpGroup;

	/*检查上联带宽是否超过最大值 */
	if (CheckUpBandwidth (ReceiveIgmpMsg.unGroupAddress) == -1)
	{
		return;
	}

	if (ReceiveIgmpMsg.ucIGMPType == IGMPV3MembershipReport)
	{
		if (ReceiveIgmpMsg.unDestinationAddress != 0xe0000016)
		{
			ulATMReceiveIgmpBad++;
			if (bIgmpDebug)
			{
				printf ("RouterProcessIgmpV3Report Receive Bad Pkt!\n");
			}
			return;
		}
	}
	else
	{
		if (ReceiveIgmpMsg.unDestinationAddress !=
			ReceiveIgmpMsg.unGroupAddress)
		{						/*Report包的目的IP和组地址必须一致 */
			ulATMReceiveIgmpBad++;
			if (bIgmpDebug)
			{
				printf ("RouterProcessIgmpV2Report Receive Bad Pkt!\n");
			}
			return;
		}
	}

	if (						/*(ReceiveIgmpMsg.unGroupAddress <= 0xe00000ff) || */
		(ReceiveIgmpMsg.unGroupAddress > 0xefffffff))
	{							/*Report包的目的IP应该在224.0.1.0到239.255.255.255之间 */
		/*IANA预留224.0.0.1到224.0.0.255的组播地址,为路由协议以及其他低级拓扑查找及维护协议使用 
		   224.0.0.1    所有主机
		   224.0.0.2    所有路由器
		   224.0.0.3    不分配
		   224.0.0.4    DVMRP路由器
		   224.0.0.5    OSPF路由器
		   224.0.0.6    OSPF指定路由器
		   224.0.0.7    ST路由器
		   224.0.0.8    ST主机
		   224.0.0.9    RIP2路由器
		   224.0.0.10   IGRP路由器
		   224.0.0.11   活动代理
		   224.0.0.12   DHCP服务器、中继代理
		   224.0.0.13   所有PIM路由器
		   224.0.0.14   PSVP封装
		   224.0.0.15   所有CBT路由器
		   224.0.0.16   指定SBM
		   224.0.0.17   所有SBM
		   224.0.0.18   VRRP
		   224.0.0.19~224.0.0.255   不分配
		   224.0.1.0    VMTP管理组
		   224.0.1.1    网络时间协议
		   224.0.1.2    SGI Dogfight
		   224.0.1.3    Rwhod
		   224.0.1.4    VNP
		   224.0.1.5    人工界限Artificial Horizons
		   224.0.1.6    名称维护服务器
		   224.0.1.7    声音新闻组AudioNews
		   224.0.1.8    SUN NIS+信息服务
		   224.0.1.9    MTP组播传输协议
		   224.0.1.10   IETF-1-LOW-AUDIO
		   224.0.1.11   IETF-1-AUDIO
		   224.0.1.12   IETF-1-VIDEO
		   224.0.1.13   IETF-2-LOW-AUDIO
		   224.0.1.14   IETF-2-AUDIO
		   224.0.1.15   IETF-2-VIDEO
		   224.0.1.16   MUSIC-SERVICE
		   224.0.1.17   SEANET-TELEMETRY
		   224.0.1.18   SEANET-IMAGE
		   224.0.1.19   MLOADD
		   224.0.1.20   任何私人实验
		   224.0.1.21   MOSPF上的DVMRP
		   224.0.1.32   Mtrace
		   224.0.1.33   RSAP封装1
		   224.0.1.34   RSAP封装2
		   224.0.1.39   Cisco RP公告
		   224.0.1.40   Cisco RP发现
		   224.0.1.80~224.0.1.255   不分配
		 */
		ulATMReceiveIgmpBad++;
		if (bIgmpDebug)
		{
			printf ("RouterProcessIgmpV2Report Receive Reserved IP!\n");
		}
		return;
	}

	IgmpGroup = FindIgmpGroupByAddress (ReceiveIgmpMsg.unGroupAddress);
	if (IgmpGroup == NULL)		/*组播组不存在 */
	{
		if ((usCurrentUser >= usMaxUser) || (usCurrentGroup > MaxGroup))
		{						/*达到容量限制 */
			return;
		}
		/*printf("组播组不存在,新建组播组\n"); */
		IgmpGroup = AddNewIgmpGroup (ReceiveIgmpMsg.unGroupAddress);

		/*IgmpGroup->OutVlanTag = GetGroupVlan(ReceiveIgmpMsg.unGroupAddress); eidt by aibin 20080404 */

		if (IgmpGroup == NULL)
		{
			printf ("AddNewIgmpGroup FAIL!\n");
			return;
		}
		semTake (semIgmpDelete, WAIT_FOREVER);
		AddPortToSpecificGroup (ReceiveIgmpMsg.unGroupAddress, ReceiveIgmpMsg.usPort);	/*通知底层 */
		IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] = MembersPresent;
		/*启动定时器 */
		if (!IfPreJoinNodeExist (ReceiveIgmpMsg.unGroupAddress))	/*如果不是预加入的组就发加入报文 2006.8.8 */
			SpecificGroupSendV2Report (ReceiveIgmpMsg.unGroupAddress);
		/*StartHostReportDelayTimer (IgmpGroup, usUnsolicitedReportInterval); */
		StartGroupPortV2MembershipTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
		AddPortToSearchGroup (IgmpGroup, ReceiveIgmpMsg.usPort);
		usCurrentUser++;
		semGive (semIgmpDelete);
		/*printf("User++\n"); */

	}
	else						/*组播组已经存在 */
	{
		if (!FindPortInSpecificGroup (IgmpGroup, ReceiveIgmpMsg.usPort))	/*端口不存在 */
		{
			if (usCurrentUser >= usMaxUser)
			{					/*达到容量限制 */
				return;
			}
			/*printf("组播组已经存在,添加端口\n"); */
			semTake (semIgmpDelete, WAIT_FOREVER);
			AddPortToSpecificGroup (ReceiveIgmpMsg.unGroupAddress,
				ReceiveIgmpMsg.usPort);
			IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] = MembersPresent;
			IgmpGroup->usGroupUserNumber++;
			StartGroupPortV2MembershipTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
			AddPortToSearchGroup (IgmpGroup, ReceiveIgmpMsg.usPort);
			/*通知底层 */
			AddPortToGroup (ReceiveIgmpMsg.unGroupAddress,
				ReceiveIgmpMsg.usPort);
			usCurrentUser++;
			semGive (semIgmpDelete);
			/*printf("User++\n"); */
		}
		else					/*端口已经存在 */
		{
			/*printf("端口已经存在,刷新定时器\n"); */
			if (IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] ==
				CheckingMembership)
			{
				StopGroupPortLastMemberQueryTimer (IgmpGroup,
					ReceiveIgmpMsg.usPort);
				IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] =
					MembersPresent;
			}
			StartGroupPortV2MembershipTimer (IgmpGroup, ReceiveIgmpMsg.usPort);
		}
		testReceieveJoin++;
	}
}

/***************************************************
函数名称:RouterProcessIgmpLeave
函数功能:处理IGMP Leave包
输入参数:ReceiveIgmpMsg 接收到的IGMP包 
返回值:	 无
***************************************************/
void RouterProcessIgmpLeave (IGMPMsg ReceiveIgmpMsg)
{
	GroupEntity *IgmpGroup;

	if ((ReceiveIgmpMsg.unDestinationAddress != 0xe0000002) && (ReceiveIgmpMsg.unDestinationAddress != ReceiveIgmpMsg.unGroupAddress))	/*数据包非法 */
	{							/*RFC2236规定离开包的地址应该是224.0.0.2,但为了提高兼容性,目的IP和组播组地址一致也可以。 */
		ulATMReceiveIgmpBad++;
		if (bIgmpDebug)
		{
			printf ("RouterProcessIgmpLeave Receive Bad Pkt!\n");
		}
		return;
	}
	if (!bQuerierFlag)			/*非查询者状态下忽略离开报文 */
	{
		ulATMReceiveIgmpBad++;
		return;
	}

	IgmpGroup = FindIgmpGroupByAddress (ReceiveIgmpMsg.unGroupAddress);

	if (IgmpGroup == NULL)		/*没有找到该组 */
	{
		//printf ("RouterProcessIgmpLeave:No such a group!\n");
		return;
	}
	if (!FindPortInSpecificGroup (IgmpGroup, ReceiveIgmpMsg.usPort))
	{							/*该组中没有这个成员端口 */
		//printf ("RouterProcessIgmpLeave:No such a port!\n");
		return;
	}
	if (IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] ==
		CheckingMembership)
	{
		//printf ("RouterProcessIgmpLeave:port == Checking!\n");
		return;
	}
	if (IgmpGroup->bGroupV1HostPresentFlag)	/*该组有V1成员 */
	{
		if (IgmpGroup->eGroupPortStatus[ReceiveIgmpMsg.usPort] !=
			MembersPresent)
		{
			return;
		}
	}
	DeletePortFromSpecificGroup (IgmpGroup, ReceiveIgmpMsg.usPort,
		ReceiveIgmpMsg.user);
	testReceiveLeave++;
	/*move */
}

/***************************************************
函数名称:AddPortToSpecificGroup
函数功能:将端口加入指定组播组
输入参数:unGroupAddress 组播组地址
		 usPort 指定的端口 
返回值:	 无
***************************************************/
void AddPortToSpecificGroup (UINT unGroupAddress, USHORT usPort)
{
	/*printf("AddPortToGroup:0x%x,0x%x\n",usPort,unGroupAddress); */
	AddPortToGroup (unGroupAddress, usPort);	/*由底层提供的接口函数 */
}

/***************************************************
函数名称:DeletePortFromSpecificGroup
函数功能:将端口从指定组播组中删除
输入参数:IgmpGroup 指向组播组的指针
		 usPort 指定的端口 
返回值:	 无
***************************************************/
void DeletePortFromSpecificGroup (GroupEntity * IgmpGroup, USHORT usPort,
	int user)
{
	int leavedelaytime;

	if (semIgmpDelete == NULL)
	{
		return;
	}

	/*printf("Port %d 离开\n",usPort); */
	if (IgmpGroup->eGroupPortStatus[usPort] != MembersPresent)
	{
		return;
	}

	semTake (semIgmpDelete, WAIT_FOREVER);	/*信号量保护 */

	leavedelaytime = GetLeaveDelay (IgmpGroup->unGroupAddress);
	if (bEnableInstantLeave && !leavedelaytime)	/*允许端口开速离开 */
	{
		/*printf("DelPortFromGroup:0x%x,%d\n",IgmpGroup->unGroupAddress,usPort); */
		DelPortFromGroup1 (IgmpGroup->unGroupAddress, usPort);	/*由底层提供的接口函数 */
		//StopGroupPortV2MembershipTimer (IgmpGroup->   tGroupPortV2MembershipTimer[usPort]);
		DelPortFromSearchGroup (IgmpGroup, usPort);

⌨️ 快捷键说明

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