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

📄 igmp_snoop.c

📁 harmmer-os的其中一个部分代码 。
💻 C
📖 第 1 页 / 共 5 页
字号:
	#ifdef _U_24_IGMPSNOOPING_
		if ((daddr == 0x020000e0) || (daddr == 0x040000e0) ||(daddr == 0x050000e0) || \
				(daddr == 0x060000e0) ||(daddr == 0x0d0000e0 ))
		{
			IGMP_ETHER_MAP_IP_MULTICAST(&daddr, enaddr);
			kfree(rec_pkt_msg);
			rec_pkt_msg = NULL;
			igmp_other_router_pkt_process(VID,port_no, pkt , len,enaddr,saenaddr,daenaddr);
			send_query(VID,pkt,len,port_no,enaddr,saenaddr,daenaddr,vlanhdr_for_send,tag_flag);
			kfree(pkt);
			pkt = NULL;

		}
	#endif


	else if (iph_proto == 2)	
	{	
		#ifdef _FLEX_HAMMER_
			timer = ntohs(ih->code);
			group_addr = ntohl(ih->group); 
		#endif
		#ifdef _U_24_IGMPSNOOPING_
			timer = ih->code;
			group_addr = ih->group;       
		#endif
		timer = timer*(1000/IGMP_TIMER_SCALE);
	
		IGMP_ETHER_MAP_IP_MULTICAST(&group_addr, enaddr);
		
		switch(ih_type)
		{
			case IGMP_MEMBERSHIP_QUERY:   /*embership query         */
			{
			
/*				int port_no_to_send = 0;*/
/*				int i = 0;*/
				kfree(rec_pkt_msg);
				rec_pkt_msg = NULL;
				igmp_memebership_query_process(port_no, timer ,VID);
				send_query(VID,pkt,len,port_no,enaddr,saenaddr,daenaddr,vlanhdr_for_send,tag_flag);
				kfree(pkt);
				pkt = NULL;
				break;
			}
			
			case IGMP_V1_MEMBERSHIP_REPORT:		/* Ver. 1 membership report */
			{
			
				int send_general_report ,i,port_no_to_send;
				struct igmp_snoop_mac_group *igmp_snoop_mac_to_join = igmp_snoop_mac_find(VID,enaddr);
				kfree(rec_pkt_msg);
				rec_pkt_msg =NULL;
				if (igmp_snoop_mac_to_join != NULL)
				{
					igmp_snoop_group_to_join = igmp_snoop_group_find(igmp_snoop_mac_to_join, group_addr);
					if (igmp_snoop_group_to_join != NULL)
						send_general_report = igmp_snoop_group_to_join->send_general_report;
				}
				else
				{
					send_general_report = TRUE;
				}
				igmp_memebership_report_process(port_no,ih_type, VID, enaddr, group_addr );
				/*if the send_general_report is true ,then we should send the ports of this group*/
				if (send_general_report == TRUE)
				{
					/*send the reports to ports of the group*/
					igmp_snoop_mac_to_find = igmp_snoop_mac_find(VID, enaddr);
					if ( NULL == igmp_snoop_mac_to_find)
					{
						kfree(pkt);
						pkt =NULL;
						return NULL;
					}
					igmp_snoop_group_to_find = igmp_snoop_group_find(igmp_snoop_mac_to_find, group_addr );
					if ( NULL == igmp_snoop_group_to_find)
					{
						kfree(pkt);
						pkt =NULL;
						return NULL;
					}
					for (i = 0; i < MAXPortNum; i ++)
					{
						port_no_to_send = igmp_snoop_group_to_find->port_no_list[i];
						if ((port_no_to_send >0) && (port_no_to_send != port_no))
							igmp_snoop_send(VID,port_no_to_send, pkt, len,enaddr,saenaddr,daenaddr,vlanhdr_for_send,tag_flag);
					}
					/*should be changed ,if the 10s timer is on*/
				/*	igmp_snoop_group_to_find->send_general_report = TRUE;*/
					igmp_snoop_group_to_find->send_general_report = FALSE;
				}
				kfree(pkt);
				pkt =NULL;
				break;
			}
			case IGMP_V2_MEMBERSHIP_REPORT:		/* Ver. 2 membership report */
			{
				int send_general_report,i;
				int port_no_to_send = 0;
				struct igmp_snoop_router_entry *p;
				struct igmp_snoop_mac_group *igmp_snoop_mac_to_join = igmp_snoop_mac_find(VID,enaddr);
				kfree(rec_pkt_msg);
				rec_pkt_msg =NULL;
				if (igmp_snoop_mac_to_join != NULL)
				{
					igmp_snoop_group_to_join = igmp_snoop_group_find(igmp_snoop_mac_to_join, group_addr);
					if (igmp_snoop_group_to_join != NULL)
						send_general_report = igmp_snoop_group_to_join->send_general_report;
				}
				else
				{
					send_general_report = TRUE;
				}		
				igmp_memebership_report_process(port_no,ih_type, VID, enaddr, group_addr );
				/*if the send_general_report is true ,then we should send the pkt to router ports*/
				if (send_general_report == TRUE)
				{
					/*send the reports to ports of the group*/
					igmp_snoop_mac_to_find = igmp_snoop_mac_find(VID, enaddr);
					if ( NULL == igmp_snoop_mac_to_find)
					{
						kfree(pkt);
						pkt =NULL;
						return NULL;
					}
					igmp_snoop_group_to_find = igmp_snoop_group_find(igmp_snoop_mac_to_find, group_addr );
					if ( NULL == igmp_snoop_group_to_find)
					{
						kfree(pkt);
						pkt =NULL;
						return NULL;
					}
					for (i = 0; i < MAXPortNum; i ++)
					{
						port_no_to_send = igmp_snoop_group_to_find->port_no_list[i];
						if ((port_no_to_send >0) && (port_no_to_send != port_no))
						{
							p = igmp_snoop_router_find(port_no_to_send,VID);
							if ((p == NULL) ||((p != NULL)&& (p->router_v1flag == FALSE)))
							igmp_snoop_send(VID,port_no_to_send, pkt, len,enaddr,saenaddr,daenaddr,vlanhdr_for_send,tag_flag);
						}		
					}
					/*should be changed ,if the 10s timer is on*/
/*					igmp_snoop_group_to_find->send_general_report = TRUE;  */
					igmp_snoop_group_to_find->send_general_report = FALSE;
				}
				kfree(pkt);
				pkt =NULL;
			/*	send_general_report = FALSE;*/
				break;
			}

			case IGMP_V2_LEAVE_GROUP:			/* Leave-group message	    */
			{
				int port_no_to_send = 0,i;
				int send_to_router_or_not = TRUE;
				struct igmp_snoop_router_entry *p;
				kfree(rec_pkt_msg);
				rec_pkt_msg = NULL;
				
				/*first we should check if the group has IGMPV1 host*/
				igmp_snoop_mac_to_find = igmp_snoop_mac_find(VID, enaddr);
				if(igmp_snoop_mac_to_find == NULL) 
				{
					kfree(pkt);
					pkt = NULL;
					break;
				}
				igmp_snoop_group_to_find = igmp_snoop_group_find(igmp_snoop_mac_to_find, group_addr );
				if(igmp_snoop_group_to_find == NULL)
				{
					kfree(pkt);
					pkt = NULL;
					break;
				}
				for (port_no_to_send = 0; port_no_to_send < MAXPortNum; port_no_to_send ++)
				{
					if (igmp_snoop_group_to_find->host_v1flag[port_no_to_send] == TRUE)
					{
						port_no_to_send = MAXPortNum;
						send_to_router_or_not = FALSE;
					}
				}
				/*if the group doesn't have IGMPV1 host ,the report should be sent to the routers*/
				if (send_to_router_or_not == TRUE)
				{
					/*send the reports to ports of the group*/
					igmp_snoop_mac_to_find = igmp_snoop_mac_find(VID, enaddr);
					igmp_snoop_group_to_find = igmp_snoop_group_find(igmp_snoop_mac_to_find, group_addr );
					for (i = 0; i < MAXPortNum; i ++)
					{
						port_no_to_send = igmp_snoop_group_to_find->port_no_list[i];
						if ((port_no_to_send >0) && (port_no_to_send != port_no))
						{
							/*only the IGMPV2 routers can receive the leave group report*/
							p = igmp_snoop_router_find(port_no_to_send, VID);
							if ((p == NULL) || ((p !=NULL) &&(p->router_v1flag == FALSE)))
							igmp_snoop_send(VID,port_no_to_send, pkt, len,enaddr,saenaddr,daenaddr,vlanhdr_for_send,tag_flag);
						}		
					}
				}
				kfree(pkt);
				pkt = NULL;
				break;
			}
		}
	}
}

igmp_pkt_check_flex(char *vlanpkt ,int len)
{
	char dest_macaddr[6],dest_ipaddr_mac[6],group_addr_mac[6];
	unsigned long dest_ipaddr,ihl,iph_proto;
	unsigned long group_addr;
	struct iphdr *iph;
	char *pkt;
	struct igmphdr *ih;
	int ip_checksum,igmp_checksum;
	memcpy(dest_macaddr, vlanpkt, ETH_ALEN);
	len = len - sizeof(struct vlanhdr);
	pkt =  (char *)kmalloc(len , IGMP_SNOOPING_MOD_ID);
	if(NULL == pkt)
		return ERROR;
	bzero ((char *)pkt, len);
	memcpy(pkt,vlanpkt + sizeof(struct vlanhdr),len);
	iph = (struct iphdr *)pkt;
	iph_proto = ntohs(iph->protocol);
	
	if(iph_proto != 2)
	{
		kfree(pkt);
		return ERROR;
	}
	dest_ipaddr = ntohl(iph->daddr);
	ihl = ntohs(iph->ihl);
	ih = (struct igmphdr *)(pkt + ihl * 4);

	/*add for the checksum*/
	bzero ((char*)&(iph->check), sizeof (u_int16_t));
	bzero ((char*)&(ih->csum), sizeof (u_int16_t));
			
	ip_checksum = hos_in_cksum(pkt,(ntohs(iph->ihl) * 4));
	igmp_checksum = hos_in_cksum((char *)ih,8);

	/*end for the checksum*/
	group_addr = ntohl(ih->group);
	IGMP_ETHER_MAP_IP_MULTICAST(&dest_ipaddr, dest_ipaddr_mac);
	if (memcmp((char *)dest_ipaddr_mac,(char *)dest_macaddr,6))
	{
		kfree(pkt);
		return ERROR;
	}
	if (group_addr != 0)
	{
		IGMP_ETHER_MAP_IP_MULTICAST(&group_addr, group_addr_mac);
		if (memcmp((char *)dest_ipaddr_mac,(char *)group_addr_mac,6))
		{
			kfree(pkt);
			return ERROR;
		}
	}
	kfree(pkt);
	return OK;
}


igmp_pkt_check(char *vlanpkt ,int len)
{
	char dest_macaddr[6],dest_ipaddr_mac[6],group_addr_mac[6];
	unsigned long dest_ipaddr,ihl,iph_proto;
	unsigned long group_addr;
	struct iphdr *iph;
	char *pkt;
	struct igmphdr *ih;
	memcpy(dest_macaddr, vlanpkt, ETH_ALEN);
	len = len - sizeof(struct vlanhdr);
	pkt =  (char *)kmalloc(len , IGMP_SNOOPING_MOD_ID);
	if(NULL == pkt)
		return ERROR;
	bzero ((char *)pkt, len);
	memcpy(pkt,vlanpkt + sizeof(struct vlanhdr),len);
	iph = (struct iphdr *)pkt;
	iph_proto = iph->protocol;
	if(iph_proto != 2)
	{
		kfree(pkt);
		return ERROR;
	}
	dest_ipaddr = iph->daddr;
	ihl = iph->ihl;
	ih = (struct igmphdr *)(pkt + ihl * 4);
	group_addr = ih->group;
	IGMP_ETHER_MAP_IP_MULTICAST(&dest_ipaddr, dest_ipaddr_mac);
	if (memcmp((char *)dest_ipaddr_mac,(char *)dest_macaddr,6))
	{
		kfree(pkt);
		return ERROR;
	}
	if (group_addr != 0)
	{
		IGMP_ETHER_MAP_IP_MULTICAST(&group_addr, group_addr_mac);
		if (memcmp((char *)dest_ipaddr_mac,(char *)group_addr_mac,6))
		{
			kfree(pkt);
			return ERROR;
		}
	}
	kfree(pkt);
	return OK;
}
/***************************************************************************************************
*	Func:	igmp_other_router_pkt_process
*This function processes the other router packet.
*Input: port_no - the port no from which the packet is received
*Output: OK  -the packet is normally processed
*	ERROR - meets error when processing the packet 
****************************************************************************************************/
int igmp_other_router_pkt_process(short VID,short port_no, char *pkt ,int len ,unsigned char enaddr[6],unsigned char saenaddr[6],unsigned char daenaddr[6])
{
	int router_port_no = 0;
	int del_timer_return;
	long timer;
	struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg;
	struct igmp_snoop_router_entry *p = igmp_snoop_router_list;
	struct igmp_snoop_router_entry *igmp_snoop_router_entry_to_find = igmp_snoop_router_find(port_no,VID);
	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));
	igmp_snoop_pkt_msg->port_no = port_no;
	igmp_snoop_pkt_msg->time_out_type = OTHER_ROUTER_TIME_OUT;
	igmp_snoop_pkt_msg->VID = VID;
	timer = 400000 ;  /*temporary*/  
	if (igmp_snoop_router_entry_to_find != NULL)
	{		
			del_timer_return = hos_deltimer(igmp_snoop_router_entry_to_find->timer_id);
			if(ERROR == del_timer_return)
			{
				kfree(igmp_snoop_pkt_msg);
				return ERROR;
			}
			igmp_snoop_router_entry_to_find->router_timer = ROUTER_TIME_OUT_TIMER;/* temporary*/
/*			hos_deltimer(igmp_snoop_router_entry_to_find->timer_id);*/
			igmp_snoop_router_entry_to_find->timer_id = 0;
			kfree(igmp_snoop_router_entry_to_find ->rec_pkt_msg);
			igmp_snoop_router_entry_to_find ->rec_pkt_msg = NULL;
			igmp_snoop_router_entry_to_find->timer_id = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, ROUTER_TIME_OUT_TIMER, NULL, (char *) igmp_snoop_pkt_msg);
	}
	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,timer,VID);
		igmp_snoop_router_entry_to_find->timer_id = hos_timerout_byqueue((unsigned long)IgmpSnoopMsgQId, ROUTER_TIME_OUT_TIMER, NULL, (char *) igmp_snoop_pkt_msg);
	}
	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; 
	
}


/***************************************************************************************************
*	Func:	igmp_memebership_query_process
*This function processes the received igmp_memebership_query packet.
*Input: port_no  - the port_no from which received this packet
*      timer    - the lifetime of router(maybe 120s)
*Output:OK  -the packet is normally disposed
*	ERROR - meets error when processing the packet  	
****************************************************************************************************/

int igmp_memebership_query_process(int port_no,  long timer, int VID )
{
	struct igmp_snoop_router_entry *igmp_snoop_router_entry_to_find = igmp_snoop_router_find(port_no,VID);
/*	char *router_parg = "router";*/
	struct igmp_snoop_pkt_msg *igmp_snoop_pkt_msg, *igmp_snoop_pktv1_msg;
	struct st_timer *p_timer_to_del;
	int del_timer_return;
	/*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;
	   /*	return 0;*/
	}
	igmp_snoop_pkt_msg->port_no = port_no;
	igmp_snoop_pkt_msg->time_out_type = ROUTER_TIME_OUT;
	igmp_snoop_pkt_msg->VID = VID;
	
	if (igmp_snoop_router_entry_to_find != NULL)
	{
		del_timer_return = hos_deltimer(igmp_snoop_router_entry_to_find->timer_id);
		if(ERROR == del_timer_return)
		{
			kfree(igmp_snoop_pkt_msg);
			return ERROR;
		}
	/*	hos_deltimer(igmp_snoop_router_entry_to_find->timer_id);*/
		igmp_snoop_router_entry_to_find->timer_id = 0;
		kfree(igmp_snoop_router_entry_to_find->rec_pkt_msg);
		igmp_snoop_router_entry_to_find->rec_pkt_msg = NULL;
		/*it is a router v1 query,so we should create a new router v1 type timer and v1 msg*/

⌨️ 快捷键说明

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