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

📄 igmp_cli.c

📁 igmp for switch in vxworks
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "igmpcon.h"

#define OK 0
/*
#define MAXPortNum2 32
#ifdef _AN2200_06_
#define usMaxPort  12
#define UPLINKSLOT 5
#else 
#define usMaxPort 24
#define UPLINKSLOT 29
#endif
*/
extern BOOL igmpageflag;

void free_grouplist(void)
{
	GroupEntity *ptemp;
	SearchNode *ps;

	semTake(semIgmpDelete, 10);
	if (NULL == pGroupEntityList)  
	{
		semGive(semIgmpDelete);
		return;
	}

	while (pGroupEntityList)
	{
		ptemp = pGroupEntityList;
		ps = ptemp->pNode;
		DelGroup(ptemp->unGroupAddress);
		pGroupEntityList = pGroupEntityList->pNext;
		while (ptemp->pNode)
		{
			ps = ptemp->pNode;
			ptemp->pNode = ptemp->pNode->pNext;
			free (ps);
			ps = NULL;
			ps->pNext = NULL;
		}
		free (ptemp);
		ptemp = NULL;
	}
	semGive(semIgmpDelete);
	usCurrentGroup = 0;
	return;
}

extern SEM_ID semIgmpTimeOut;
void stop_igmp(void)
{
      /*StopGeneralQueryTimer();
       StopStartupQueryTimer();
       StopOtherQuerierPresentTimer(); */
	StopV1RouterPresentTimer();
	StopIgmpMembershipTimer();
		
	taskDelete(nIGMPTaskId);
	nIGMPTaskId = 0;
	msgQDelete(IGMPMsgQId);

       semTake(semIgmpDelete,WAIT_FOREVER);
	/*free_authlist();
	free_previewlist();*/
	free_grouplist();
	
	semGive(semIgmpDelete);
	
       semDelete(semIgmpDelete);
	semDelete(semIgmpReceive); 
	semDelete(semIgmpTimeOut);
	semDelete (semPreJoin);
      	
	/*关闭igmp snooping */
	driver_igmpdisable ();
	#ifdef _AN5116_06A_
		driver_dtag_igmpdisable();
	#endif
	/* IS_Stop ();*/	
	return;
}


PreJoinNode *IfPreJoinNodeExist (UINT unGroupAddress)
	{
		PreJoinNode *PreJoinNodeTemp;
		UINT unReturnCode = 0;

		if (pPreJoinList == NULL)
			return NULL;
		PreJoinNodeTemp = pPreJoinList;
		while (PreJoinNodeTemp)
		{
			if (PreJoinNodeTemp->unGroupAddress == unGroupAddress)
				return PreJoinNodeTemp;
			else
				PreJoinNodeTemp = PreJoinNodeTemp->pNext;
		}
		return NULL;
	}

	int AddPreJoinNode (UINT unGroupAddress)
	{
		PreJoinNode *PreJoinNodeTemp;

		semTake (semPreJoin, WAIT_FOREVER);
		if ((IfPreJoinNodeExist (unGroupAddress) == NULL)
			&& (usCurrentPreJoinNode < usMaxPreJoin))
		{
			PreJoinNodeTemp = (PreJoinNode *) malloc (sizeof (PreJoinNode));
			if (PreJoinNodeTemp == NULL)
			{
				semGive (semPreJoin);
				return ERROR;
			}
			PreJoinNodeTemp->unGroupAddress = unGroupAddress;
			PreJoinNodeTemp->usCount = 0;
			PreJoinNodeTemp->pNext = pPreJoinList;
			pPreJoinList = PreJoinNodeTemp;
			usCurrentPreJoinNode++;
			SpecificGroupSendV2Report (unGroupAddress);
		}
		else
		{
			printf("Group already exist or reach the maximum prejoin groups.\r\n");
			semGive (semPreJoin);
			return ERROR;
		}
		semGive (semPreJoin);
		return OK;
	}

	void DelPreJoinNode (UINT unGroupAddress)
	{
		PreJoinNode *PreJoinNodeTemp1;
		PreJoinNode *PreJoinNodeTemp2;

		if (IfPreJoinNodeExist (unGroupAddress) == NULL)
			return;
		semTake (semPreJoin, WAIT_FOREVER);
		PreJoinNodeTemp1 = pPreJoinList;
		if (PreJoinNodeTemp1->unGroupAddress == unGroupAddress)
		{
			pPreJoinList = PreJoinNodeTemp1->pNext;
			PreJoinNodeTemp1->unGroupAddress = 0;
			PreJoinNodeTemp1->usCount = 0;
			PreJoinNodeTemp1->pNext = NULL;
			free ((void *) PreJoinNodeTemp1);
			usCurrentPreJoinNode--;
			semGive (semPreJoin);
			return;
		}
		PreJoinNodeTemp2 = PreJoinNodeTemp1->pNext;
		while (PreJoinNodeTemp2)
		{
			if (PreJoinNodeTemp2->unGroupAddress == unGroupAddress)
			{
				PreJoinNodeTemp1->pNext = PreJoinNodeTemp2->pNext;
				PreJoinNodeTemp2->unGroupAddress = 0;
				PreJoinNodeTemp2->usCount = 0;
				PreJoinNodeTemp2->pNext = NULL;
				free ((void *) PreJoinNodeTemp2);
				usCurrentPreJoinNode--;
				semGive (semPreJoin);
				return;
			}
			else
			{
				PreJoinNodeTemp1 = PreJoinNodeTemp2;
				PreJoinNodeTemp2 = PreJoinNodeTemp2->pNext;
			}

		}
		semGive (semPreJoin);

	}

	void DelAllPreJoinNode (void)
	{
		PreJoinNode *PreJoinNodeTemp;
		PreJoinNode *PreJoinNodeTemp1;

		if (pPreJoinList == NULL)
		{
			return;
		}
		semTake (semPreJoin, WAIT_FOREVER);
		PreJoinNodeTemp = pPreJoinList->pNext;
		pPreJoinList->unGroupAddress = 0;
		pPreJoinList->usCount = 0;
		pPreJoinList->pNext = NULL;
		free ((void *) pPreJoinList);
		usCurrentPreJoinNode--;
		while (PreJoinNodeTemp)
		{
			PreJoinNodeTemp1 = PreJoinNodeTemp->pNext;
			PreJoinNodeTemp->unGroupAddress = 0;
			PreJoinNodeTemp->usCount = 0;
			PreJoinNodeTemp->pNext = NULL;
			free ((void *) PreJoinNodeTemp);
			usCurrentPreJoinNode--;
			PreJoinNodeTemp = PreJoinNodeTemp1;
		}
		pPreJoinList = NULL;
		semGive (semPreJoin);
	}


	int get_all_prejoin (char *buf, USHORT *len)
	{
		char *p;
		PreJoinNode *ptmp;
		int count;

		semTake (semPreJoin, WAIT_FOREVER);
		ptmp = pPreJoinList;
		p = buf;
		*(int *)p = 1;
		p += 4;
		*p = get_prejoin_count();
		count = *p;
		p++;
		*len = count*4 + 1;

		while (ptmp)
		{
			*(UINT *)p = ptmp->unGroupAddress;
			p+= 4;
			ptmp = ptmp->pNext;
		}
		*len = p-buf;
		semGive (semPreJoin);
		return OK;

	}

	int get_prejoin_count (void)
	{
		PreJoinNode *ptmp;
		int count;

		ptmp = pPreJoinList;
		count = 0;
		while (ptmp)
		{
			count++;
			ptmp = ptmp->pNext;
		}
		return count;
	}

	int get_prejoin_group (UINT * group)
	{
		UINT gip[256];
		PreJoinNode *ptmp;
		int i;

		memset (gip, 0, 1024);
		i = 0;
		ptmp = pPreJoinList;
		while (ptmp)
		{
			gip[i] = ptmp->unGroupAddress;
			i++;
			ptmp = ptmp->pNext;
		}

		bcopy ((char *) gip, (char *) group, 1024);
		return OK;
	}


int start_igmp_proxy (char *act, struct vty *vty)
{
	if(strcmp(act, "enable") == 0)
	{
		if (nIGMPTaskId )
		{
			return OK;
		}
		IgmpInit();
	}
	else 
	{
		if (nIGMPTaskId == 0)
		{
			return OK;
		}
		stop_igmp();
		return OK;
	}
}	
int show_igmp_stat (struct vty *vty)
{
	char on[] = "ON";
	char echo[] = "OFF";
			
	if (!tIgmpMembershipTimer)
	{
		vty_out (vty, "IGMP is OFF\r\n");
		return OK;
	}
	vty_out (vty, "IGMP Proxy is Running!\r\n");
	return OK;
}	

		
int showgroupusernew (unsigned int groupaddress, struct vty *vty)
{
	GroupEntity *ptemp;
	int i, j, k;
	int sum;
	struct in_addr gip;
	
	ptemp = pGroupEntityList;
	sum = 0;
	/*显示所有组信息*/
	if (groupaddress == 0)
	{
		vty_out (vty, "Total Group: %d\r\n", usCurrentGroup);
		while (ptemp)
		{
			sum = 0;
			gip.s_addr = ptemp->unGroupAddress;
			vty_out (vty, "==========Group==========\r\n");
			vty_out (vty, "group(%s):   \r\n", inet_ntoa (gip));
			vty_out (vty, "slot: ");
				
			for (i = 1; i <= MAX_UPLINK_PORT; i++)
			{
				if (ptemp->eGroupPortStatus[i])
					{
						vty_out (vty, "%d, ", i);
						sum++;
					}
			}
			vty_out (vty, "\r\nTotal Group member: %d\r\n", ptemp->usGroupUserNumber);
			vty_out (vty, "====================\r\n");
			ptemp = ptemp->pNext;
		}
		return OK;
	}
	
	/*显示单个组信息*/
	while (ptemp)
	{
		if (ptemp->unGroupAddress == groupaddress)
		{
			sum = 0;
			gip.s_addr = ptemp->unGroupAddress;
			vty_out (vty, "==========Group==========\r\n");
			vty_out (vty, "group(%s):   \r\n", inet_ntoa (gip));
			vty_out (vty, "slot: ");
		
		
			for (i = 1; i <= MAX_UPLINK_PORT; i++)
			{
				if (ptemp->eGroupPortStatus[i])
				{
					vty_out (vty, "%d, ", i);
					sum++;
				}
			}
			vty_out (vty, "\r\nTotal Group member: %d\r\n", sum);
			vty_out (vty, "====================\r\n");
			return OK;
		}
		ptemp = ptemp->pNext;
	}
	return OK;
}

void ShowGroupUplink(struct vty *vty)
{
	GroupEntity *ptemp;
	int i, j, k;
	int sum;
	struct in_addr gip;
	char portlist[20];
	char ip[20];
	char uplink[10];

	vty_out (vty, "IGMP uplink ports :");
	for (i = MIN_UPLINK_PORT; i <= MAX_UPLINK_PORT; i ++)
	{
		if (slot_module[i] == HOST_MODULE_PORT)
		{
			translate_uplinkport_out (i, uplink);
			vty_out(vty, "%s, ", uplink);
		}
	}
	vty_out (vty, "\r\n");
	vty_out (vty, "IGMP cascade ports :");
	for (i = MIN_UPLINK_PORT; i <= MAX_UPLINK_PORT; i ++)
	{
		if (slot_module[i] == ROUTER_MODULE_PORT)
		{
			translate_uplinkport_out (i, uplink);
			vty_out(vty, "%s, ", uplink);
		}
	}
	vty_out (vty, "\r\n");
	memset (portlist, 0, sizeof (portlist));
	ptemp = pGroupEntityList;
	while (ptemp)
	{
		sum = 0;
		gip.s_addr = ptemp->unGroupAddress;
		k = GetUplinkPortlist(portlist, ptemp->unGroupAddress );
		if (k)
		{
			inet_ntoa_b(gip, ip);
			vty_out (vty, "Group(%s) : %s\r\n", ip, portlist);
			memset (portlist, 0, sizeof (portlist));
		}
		ptemp = ptemp->pNext;
	}
	return;
}

int show_igmp_ip (struct vty *vty)
{
	struct in_addr gip;
	char ip[20];
	gip.s_addr = gEtherInfo.ipAddr;
	inet_ntoa_b(gip,ip);
	vty_out (vty, "IGMP proxy's IP : %s\r\n", ip);
	return OK;
}

int set_igmpproxy_ip (unsigned int groupaddress)
{
	gEtherInfo.ipAddr = groupaddress;
	return OK;
}

void erase_proxy_config (void)
{
	PreJoinNode *ptmp;
	
	if (pPreJoinList != NULL)
	{
		semTake (semPreJoin, WAIT_FOREVER);
		while (pPreJoinList)
		{
			ptmp = pPreJoinList;
			pPreJoinList = pPreJoinList->pNext;
			free(ptmp);
			ptmp = NULL;
		}
		semGive (semPreJoin);
		usCurrentPreJoinNode = 0;
	}
	gEtherInfo.ipAddr = 0x0a190e39;
	return;
}

/***************************************************
函数名称:SendIgmpPktbyCmd
函数功能:发送IGMP包函数,根据需要组IGMP包,并发送。
输入参数:ucIgmpType IGMP包类型
	 	 unGroupAddress 组播组地址
	 	 usPort 数据包发送的目的端口
	 	 ucMaxRespTime 最大响应时间(查询包)
	 	 usSessionId	PPPoE用户SessionId
返回值:	 无
备注      :  修改了最终的发送函数aibin 2005-01-14
			现暂时把所有包都设置成untaged aibin 2005-4-1
***************************************************/
void SendIgmpPktbyCmd ( int ucIgmpType, UINT unGroupAddress, unsigned long  sourceip, USHORT usPort,
	UCHAR user)
{
       UCHAR *IgmpPkt = (UCHAR *) malloc (68); /*aibin*/
	/*UCHAR *IgmpPkt = (UCHAR *) device_driver_malloc ();*/
	UINT unPktLength = 68 ;                 /*与3400上的兼容, 原为64。modied by aibin ;*/
	UINT unOutPVC;
	USHORT OutVlanTag;/* = GetPortVlanTag (usPort)*/
	UINT DestinationIpAddress;
	unsigned char smac[6];
	char *userchar, *p;
	char temp[100];

	/*struct in_addr IpAddress; */
	UCHAR DestinationMacAddress[6];
	ipheader IpHeader;
	ipheaderwithoption IpHeaderWithOption;
	igmpheader IgmpHeader;
	vlantag VlanTag;
	GroupEntity *IgmpGroup;
	int vid;
	OutVlanTag = 0; /*aibin*/

	smac[0] = '5';
	smac[1] = '4';
	smac[2] = '3';
	smac[3] = '2';
	smac[4] = '1';
	smac[5] = '0';
	
	if(IgmpPkt == NULL)
	{
		printf("SendIgmpPkt:Malloc Fail\n");
		return;
	}

	memset (IgmpPkt, 0, unPktLength);
	/*if (OutVlanTag > 4094)		/*VLAN tag非法4095保留 */
	/*{                                                          */
	/*	OutVlanTag = 0;                                 */
	/*}                                                            */   

	switch (ucIgmpType)
	{
		case IGMPMembershipQuery:

			if (unGroupAddress == 0)	/*通用查询 */
			{
				DestinationIpAddress = 0xe0000001;
				IgmpEtherMapIpMulticast (ntohl (DestinationIpAddress),
					DestinationMacAddress);
				memcpy (IgmpPkt, DestinationMacAddress, 6);	/*目的Mac */
				memcpy (IgmpPkt + 6, gEtherInfo.etherMac, 6);	/*源Mac */
				IpHeader.version = 4;
				IpHeader.headerlength = 5;
				IpHeader.tos = 0;
				IpHeader.total_len = htons (0x001c);
				srand (tickGet ());
				IpHeader.id = (USHORT)rand ();
				IpHeader.frag_off = 0;
				IpHeader.ttl = 1;
				IpHeader.protocol = 2;
				IpHeader.checksum = 0;
				IpHeader.saddr = htonl (sourceip);
				IpHeader.daddr = ntohl (DestinationIpAddress);
				CaculateChecksum ((UCHAR *) & IpHeader, sizeof (ipheader), 10);
				IgmpHeader.ucType = ucIgmpType;
				IgmpHeader.ucMaxRespTime = 10 * 10;
				IgmpHeader.usChecksum = 0;
				IgmpHeader.unGroupAddress = 0;	/*通用查询组地址为零 */
				CaculateChecksum ((UCHAR *) & IgmpHeader, sizeof (igmpheader), 2);	/*计算校验和 */
				if (OutVlanTag == 0)	/*没有VLAN */
				{
					if (1)	/*无PPPoE封装 */
					{
						*(USHORT *) (IgmpPkt + 12) = ntohs (0x0800);
						memcpy (IgmpPkt + 14, &IpHeader, sizeof (ipheader));
						memcpy (IgmpPkt + 14 + sizeof (ipheader), &IgmpHeader,
							sizeof (igmpheader));
					
					}
					else		/*有PPPoE封装 */
					{
						*(USHORT *) (IgmpPkt + 12) = ntohs (0x8864);
						*(USHORT *) (IgmpPkt + 14) = ntohs (0x1100);
						*(USHORT *) (IgmpPkt + 16) =
							ntohs (usPortMapSessionId[usPort]);
						*(USHORT *) (IgmpPkt + 18) = ntohs (0x001e);
						*(USHORT *) (IgmpPkt + 20) = ntohs (0x0021);
						memcpy (IgmpPkt + 22, &IpHeader, sizeof (ipheader));
						memcpy (IgmpPkt + 22 + sizeof (ipheader), &IgmpHeader,
							sizeof (igmpheader));

					}
				}
			}
			break;
		case IGMPV1MembershipReport:
		case IGMPV2MembershipReport:

		                                           /*路由器口的vid ,mod by aibin*/
			DestinationIpAddress = unGroupAddress;
			IgmpEtherMapIpMulticast (ntohl (DestinationIpAddress),
				DestinationMacAddress);
			memcpy (IgmpPkt, DestinationMacAddress, 6);	/*目的Mac */
			memcpy (IgmpPkt + 6, smac, 6);	/*源Mac */
			IpHeaderWithOption.version = 4;
			IpHeaderWithOption.headerlength = 6;
			IpHeaderWithOption.tos = 0;
			IpHeaderWithOption.total_len = htons (0x0020);
			srand (tickGet ());
			IpHeaderWithOption.id = (USHORT)rand ();
			IpHeaderWithOption.frag_off = 0;
			IpHeaderWithOption.ttl = 1;
			IpHeaderWithOption.protocol = 2;
			IpHeaderWithOption.checksum = 0;
			IpHeaderWithOption.saddr = htonl (sourceip);
			IpHeaderWithOption.daddr = ntohl (DestinationIpAddress);
			IpHeaderWithOption.option = htonl (0x94040000);
			CaculateChecksum ((UCHAR *) & IpHeaderWithOption,
				sizeof (IpHeaderWithOption), 10);
			IgmpHeader.ucType = ucIgmpType;
			IgmpHeader.ucMaxRespTime = 0;
			IgmpHeader.usChecksum = 0;
			IgmpHeader.unGroupAddress = htonl (unGroupAddress);
			CaculateChecksum ((UCHAR *) & IgmpHeader, sizeof (igmpheader), 2);
			IgmpGroup = FindIgmpGroupByAddress (unGroupAddress);
			/*OutVlanTag = IgmpGroup->OutVlanTag;aibin*/ 
			if (1)
			{
				*(USHORT *) (IgmpPkt + 12) = ntohs (0x0800);
				memcpy (IgmpPkt + 14, &IpHeaderWithOption,
					sizeof (IpHeaderWithOption));
				memcpy (IgmpPkt + 14 + sizeof (IpHeaderWithOption), &IgmpHeader,
					sizeof (igmpheader));

⌨️ 快捷键说明

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