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

📄 igmp_snoop.c

📁 harmmer-os的其中一个部分代码 。
💻 C
📖 第 1 页 / 共 5 页
字号:
		/*and only if this query is an igmp v1 query can we del the igmpv1 timer*/
		if ((igmp_snoop_router_entry_to_find->router_v1flag == TRUE) && (timer == 0))
		{ 
			/*the router has been a router v1 type*/
			del_timer_return = hos_deltimer(igmp_snoop_router_entry_to_find->igmpv1_timer_id);
			if(ERROR != del_timer_return)
			{
				/*hos_deltimer(igmp_snoop_router_entry_to_find->igmpv1_timer_id); */  /*igmpv1_timer_id may be 0*/
				igmp_snoop_router_entry_to_find->igmpv1_timer_id = 0;
				kfree(igmp_snoop_router_entry_to_find->rec_igmpv1_pkt_msg);	
				igmp_snoop_router_entry_to_find->rec_igmpv1_pkt_msg = NULL;
		
			}
			else
				timer = 1; /*declare the query is not v1*/
			
		}
	}
	else
	{	/*on the port there is no router,so we should first add a port in the router  list*/
		igmp_snoop_router_entry_to_find = igmp_snoop_router_add(port_no, ROUTER_TIME_OUT_TIMER,VID);
	}

	igmp_snoop_router_entry_to_find->rec_pkt_msg = igmp_snoop_pkt_msg;
	igmp_snoop_router_entry_to_find->router_timer = ROUTER_TIME_OUT_TIMER;   
	igmp_snoop_router_entry_to_find->timer_id = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, ROUTER_TIME_OUT_TIMER, NULL, (char *) igmp_snoop_pkt_msg);

	/*check if the timer' value,zero presents that it is an igmpv1 router,we should create a 
	*igmp_snoop_pktv1_msg for its igmp v1 timer 
	*/
	
	if (timer == 0)
	{
		igmp_snoop_pktv1_msg =  (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
		if(NULL == igmp_snoop_pktv1_msg)
		return NULL;
		bzero ((char *)igmp_snoop_pktv1_msg, sizeof (struct igmp_snoop_pkt_msg));
		if(igmp_snoop_pktv1_msg == NULL)
		{
	       	syslog(LOG_INFO,"No free momory for new igmp_snoop_pktv1_msg");       
		   	return ERROR;
		}
		igmp_snoop_pktv1_msg->port_no = port_no;
		igmp_snoop_pktv1_msg->time_out_type = ROUTER_V1_TIME_OUT;
		igmp_snoop_router_entry_to_find->rec_igmpv1_pkt_msg = igmp_snoop_pktv1_msg;
		igmp_snoop_router_entry_to_find->igmpv1_timer_id = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, ROUTER_V1_TIME_OUT_TIMER, NULL, (char *) igmp_snoop_pktv1_msg);
		/*version 1 router present timeout is 400s*/
		igmp_snoop_router_entry_to_find->router_v1flag = TRUE;
	}	
}


/***************************************************************************************************
*	Func:	igmp_memebership_report_process
*This function processes the received igmp_memebership_report packet.
*Input: port_no  - the port_no from which received this packet
*	ih_type   -	  the type of the msg
*   VID  -   the VID to which the port_no belongs
*   enaddr -  the mac address of the packet
*   group_addr - the ip address of the group
*Output:OK  -the packet is normally disposed
*	ERROR - meets error when processing the packet  	
****************************************************************************************************/

/*int igmp_memebership_report_process(int port_no,char *pkt, int len, int VID, unsigned char enaddr[6], unsigned int group_addr )*/
int igmp_memebership_report_process(int port_no,short ih_type, int VID, unsigned char enaddr[6], unsigned int group_addr )
{	
 	long timer = GROUP_MEMEBER_SHIP_INTERVAL;       /*260s*/
	int del_timer_return;
	struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg , *igmp_snoop_pktv1_msg;
	struct igmp_snoop_mac_group *igmp_snoop_mac_to_join;
	struct igmp_snoop_group *igmp_snoop_group_to_join;
	struct igmphdr *ih;
	vlanentry *v;
	/*now we create a igmp_snoop_pkt_msg*/
	igmp_snoop_pkt_msg =  (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
	if(NULL == igmp_snoop_pkt_msg)
		return NULL;
	bzero ((char *)igmp_snoop_pkt_msg, sizeof (struct igmp_snoop_pkt_msg));
	if(igmp_snoop_pkt_msg == NULL)
	{
	      	syslog(LOG_INFO,"No free momory for new igmp_snoop_pkt_msg");       
			return ERROR;
	}
	igmp_snoop_pkt_msg->port_no = port_no;
	igmp_snoop_pkt_msg->time_out_type = GROUP_TIME_OUT;
	igmp_snoop_pkt_msg->VID = VID;
	igmp_snoop_pkt_msg->group_addr = group_addr;

	if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
	{
		igmp_snoop_pktv1_msg =  (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
		if(NULL == igmp_snoop_pktv1_msg)
			return NULL;
		bzero ((char *)igmp_snoop_pktv1_msg, sizeof (struct igmp_snoop_pkt_msg));
		if(igmp_snoop_pktv1_msg == NULL)
		{
		      	syslog(LOG_INFO,"No free momory for new igmp_snoop_pktv1_msg");       
				return ERROR;
		}
		igmp_snoop_pktv1_msg->port_no = port_no;
		igmp_snoop_pktv1_msg->time_out_type = GROUP_V1_TIME_OUT;
		igmp_snoop_pktv1_msg->VID = VID;
		igmp_snoop_pktv1_msg->group_addr = group_addr;
	}
	
	igmp_snoop_mac_to_join = igmp_snoop_mac_find(VID,enaddr);
	igmp_snoop_group_to_join = NULL;

	
	if (igmp_snoop_mac_to_join == NULL)
	{
		/*there is no the igmp_snoop_mac_group*/
		igmp_snoop_mac_to_join = igmp_snoop_mac_add(VID, enaddr);
		igmp_snoop_mac_to_join->port_no_list[0] = port_no;
		#ifdef _FLEX_HAMMER_
			v = vlan_get_by_VID(igmp_snoop_mac_to_join->VIDX);
			vlan_pseduo_add_port(v,igmp_snoop_mac_to_join->VIDX,port_no);
		#endif
		#ifdef _U_24_IGMPSNOOPING_

		u24_driver_add_igmp_snooping_port(igmp_snoop_mac_to_join->VID ,igmp_snoop_mac_to_join->macaddr.addr, port_no);
		#endif
		igmp_snoop_group_to_join = igmp_snoop_group_add(igmp_snoop_mac_to_join, group_addr);
		add_each_router_port_to_group(igmp_snoop_mac_to_join, igmp_snoop_group_to_join ,port_no);
		igmp_snoop_group_to_join->port_no_list[0] = port_no;
		igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
		/*add timer for group and port*/
		igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
		if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
		{
			igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
			igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, NULL, (char *) igmp_snoop_pktv1_msg);
			igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
		}
	}
	else
	{
		/* the igmp_snoop_mac_group has existed*/
		int i = 0;
		while((igmp_snoop_mac_to_join->port_no_list[i] != port_no) && (i<MAXPortNum))
		{
			i++;
		}
		if (igmp_snoop_mac_to_join->port_no_list[i] == port_no) 
		{
			/*the mac group has existed , also as the port no */
			igmp_snoop_group_to_join = igmp_snoop_group_find(igmp_snoop_mac_to_join, group_addr);
			if (igmp_snoop_group_to_join == NULL)
			{
				/*the igmp_snoop_group doesn't exist*/
				igmp_snoop_group_to_join = igmp_snoop_group_add(igmp_snoop_mac_to_join, group_addr);
				add_each_router_port_to_group(igmp_snoop_mac_to_join, igmp_snoop_group_to_join ,port_no);
				igmp_snoop_group_to_join->port_no_list[0] = port_no;
				igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
				/*add timer for group and port*/
				igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
				igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
				if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
				{
					igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
					igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, NULL, (char *) igmp_snoop_pktv1_msg);
					igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
				}
				
			}
			else
			{
				/*check if the port has existed in the group,if yes then refresh the timer
				*else add the port and timer
				*/
				int i = 0;
				while((igmp_snoop_group_to_join->port_no_list[i] != port_no) && (i<MAXPortNum))
				{
					i++;
				}
				if (igmp_snoop_group_to_join->port_no_list[i] == port_no) 
				{	/* the port_no has existed,refresh the timer*/
					del_timer_return = hos_deltimer(igmp_snoop_group_to_join->timer_id[port_no]);
					if(ERROR == del_timer_return)
					{
						kfree(igmp_snoop_pkt_msg);
						if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
							kfree(igmp_snoop_pktv1_msg);
						return ERROR;
					}
					kfree(igmp_snoop_group_to_join->rec_pkt_msg[port_no]);
					igmp_snoop_group_to_join->rec_pkt_msg[port_no] = NULL;
/*					hos_deltimer(igmp_snoop_group_to_join->timer_id[port_no]);*/
					igmp_snoop_group_to_join->timer_id[port_no] = 0;
					igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
					igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
					if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
					{
						if (igmp_snoop_group_to_join->host_v1flag[port_no] == TRUE)
						{
							del_timer_return = hos_deltimer(igmp_snoop_group_to_join->igmpv1_timer_id[port_no]);
							if(ERROR == del_timer_return)
							{
								kfree(igmp_snoop_pktv1_msg);
								return ERROR;
							}
							kfree(igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no]);
							igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = NULL;
/*							hos_deltimer(igmp_snoop_group_to_join->igmpv1_timer_id[port_no]);*/
							igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = 0;
						}
						igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
						igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, NULL, (char *) igmp_snoop_pktv1_msg);
						igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
					}
				}
				else
				{  /*the port no does'nt exist*/
					int j = 0, i = 0;
					for(j = 0; j<MAXPortNum; j++)
					{
						if (igmp_snoop_group_to_join->port_no_list[j] == 0) 
						{
							i = j;
							j = MAXPortNum;
						}
					}
					igmp_snoop_group_to_join->port_no_list[i] = port_no;
					igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
					/*add the timer*/
					igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
					igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, GROUP_TIME_OUT, (char *) igmp_snoop_pkt_msg);
					if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
					{
						igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
						igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, GROUP_TIME_OUT, (char *) igmp_snoop_pktv1_msg);
						igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
					}
				}
			}
		}
		else
		{
			/*the mac group has existed , but the port no doesn't exist */
			int j = 0 , i = 0;
			for(j = 0; j<MAXPortNum; j++)
			{
				if (igmp_snoop_mac_to_join->port_no_list[j] == 0) 
				{
					i = j;
					j = MAXPortNum;
				}
			}
			igmp_snoop_mac_to_join->port_no_list[i] = port_no;
			#ifdef  _FLEX_HAMMER_
				v = vlan_get_by_VID(igmp_snoop_mac_to_join->VIDX);
				vlan_pseduo_add_port(v,igmp_snoop_mac_to_join->VIDX,port_no);
			#endif
			#ifdef _U_24_IGMPSNOOPING_
			

				u24_driver_add_igmp_snooping_port(igmp_snoop_mac_to_join->VID ,igmp_snoop_mac_to_join->macaddr.addr, port_no);
			#endif
			igmp_snoop_group_to_join = igmp_snoop_group_find(igmp_snoop_mac_to_join, group_addr);
			if (igmp_snoop_group_to_join == NULL)
			{
				/*the igmp_snoop_group doesn't exist*/
				igmp_snoop_group_to_join = igmp_snoop_group_add(igmp_snoop_mac_to_join, group_addr);
				add_each_router_port_to_group(igmp_snoop_mac_to_join, igmp_snoop_group_to_join ,port_no);
				igmp_snoop_group_to_join->port_no_list[0] = port_no;
				igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
				/*add timer for group and port*/
				igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
				igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, NULL, (char *) igmp_snoop_pkt_msg);
				if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
				{
					igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
					igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, GROUP_TIME_OUT, (char *) igmp_snoop_pktv1_msg);
					igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
				}
			}
			else
			{
				/*the igmp_snoop_group  exists, but the port no doesn't exist*/
				int j = 0, i = 0;
				for(j = 0; j<MAXPortNum; j++)
				{
					if (igmp_snoop_group_to_join->port_no_list[j] == 0) 
					{
						i = j;
						j = MAXPortNum;
					}
				}
				igmp_snoop_group_to_join->port_no_list[i] = port_no;
				/*add the timer*/
				igmp_snoop_group_to_join->rec_pkt_msg[port_no] = igmp_snoop_pkt_msg;
				igmp_snoop_group_to_join->timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, timer, GROUP_TIME_OUT, (char *) igmp_snoop_pkt_msg);
				igmp_snoop_group_to_join->host_v1flag[port_no] = FALSE;
				igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = 0;
				if(ih_type == IGMP_V1_MEMBERSHIP_REPORT)
				{
					igmp_snoop_group_to_join->rec_igmpv1_pkt_msg[port_no] = igmp_snoop_pktv1_msg;
					igmp_snoop_group_to_join->igmpv1_timer_id[port_no] = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, GROUP_V1_MEMEBER_SHIP_INTERVAL, GROUP_TIME_OUT, (char *) igmp_snoop_pktv1_msg);
					igmp_snoop_group_to_join->host_v1flag[port_no] = TRUE;
				}
			}
		}
	}
}


/***************************************************************************************************
*	Func:	other_router_port_timeout_process
*This function processes the other router port timeout msg .
*Input: msg - the msg received from msg queue 
*Output:OK  -the msg is normally processed
*	ERROR - meets error when processing the msg
****************************************************************************************************/
int other_router_port_timeout_process(TIMERMSG_S *msg)
{
	short port_no_to_del ,VID;
	struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg;
	struct igmp_snoop_router_entry *p;
	igmp_snoop_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
	port_no_to_del = igmp_snoop_pkt_msg->port_no;
	VID = igmp_snoop_pkt_msg->VID;
	p = igmp_snoop_router_find(port_no_to_del,VID);
	if (p == NULL)
		return ERROR;
	kfree(igmp_snoop_pkt_msg);
	igmp_snoop_pkt_msg = NULL;
	igmp_snoop_router_del(port_no_to_del ,VID);
}

/***************************************************************************************************
*	Func:	router_port_timeout_process
*This function processes the router port timeout msg .
*Input: msg - the msg received from msg queue 
*Output:OK  -the msg is normally processed
*	ERROR - meets error when processing the msg
****************************************************************************************************/
int router_port_timeout_process(TIMERMSG_S *msg)
{
	short port_no_to_del,VID;
	struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg;
	struct igmp_snoop_router_entry *p;
	igmp_snoop_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
	port_no_to_del = igmp_snoop_pkt_msg->port_no;
	VID = igmp_snoop_pkt_msg->VID;
	p = igmp_snoop_router_find(port_no_to_del,VID);
	if (p == NULL)
		return ERROR;
	kfree(igmp_snoop_pkt_msg);
	igmp_snoop_pkt_msg = NULL;
	igmp_snoop_router_del(port_no_to_del ,VID);
}


/***************************************************************************************************
*	Func:	group_port_timeout_process
*This function processes the group port timeout msg .
*Input: msg - the msg received from msg queue 
*Output:OK  -the msg is normally processed
*	ERROR - meets error when processing the msg
****************************************************************************************************/
int group_port_timeout_process(TIMERMSG_S *msg)
{
	int VID,VIDX;
	short port_no;
	char *pkt;
	int len, i, port_index_return;
	unsigned int group_addr;
	unsigned char enaddr[6]; 
	vlanentry * v;
	struct igmp_snoop_router_entry *p_router;
	int port_exist_flag = FALSE;
	long timer = GROUP_MEMEBER_SHIP_INTERVAL;       /*260s*/
	struct igmp_snoop_mac_group *igmp_snoop_mac_group_to_find, *p_mac;
	struct igmp_snoop_group *igmp_snoop_group_to_find, *p_group, *q_group;
	struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg, *igmp_snoop_pkt_new_msg;
	igmp_snoop_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
	VID = igmp_snoop_pkt_msg->VID;
	port_no = igmp_snoop_pkt_msg->port_no;
	group_addr = igmp_snoop_pkt_msg->group_addr;
	IGMP_ETHER_MAP_IP_MULTICAST(&group_addr, enaddr);
	igmp_snoop_mac_group_to_find = igmp_snoop_mac_find(VID, enaddr);
	if (NULL == igmp_snoop_mac_group_to_find)
		return;
	igmp_snoop_group_to_find = igmp_snoop_group_find(igmp_snoop_mac_group_to_find, group_addr);
	if (NULL == igmp_snoop_group_to_find)
		return;
	port_index_return = igmp_snoop_group_port_find(igmp_snoop_group_to_find,port_no);
	if (port_index_return == ERROR)
		return;
	/*we should first check whether there is router on this port*/
	p_router = igmp_snoop_router_find(port_no,VID);
	if (p_router != NULL) 
	{ 
	/*if there is router on this port ,so we should not delete this port
	* but we should add a new timer
	*/
		igmp_snoop_pkt_new_msg =  (struct igmp_snoop_pkt_msg *)kmalloc(sizeof (struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
		if(NULL == igmp_snoop_pkt_new_msg)
			return NULL;
		bzero ((char *)igmp_snoop_pkt_new_msg, sizeof (struct igmp_snoop_pkt_msg));
		if(igmp_snoop_pkt_new_msg == NULL)
		{
	      	syslog(LOG_INFO,"No free momory for 

⌨️ 快捷键说明

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