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

📄 igmp_snoop.c

📁 harmmer-os的其中一个部分代码 。
💻 C
📖 第 1 页 / 共 5 页
字号:
			daddr = ntohl(iph->daddr);       
		/*	ih = (struct igmphdr *)pkt;*/
		}

	#endif
	#ifdef _U_24_IGMPSNOOPING_
		iph_proto = iph->protocol;
		if(iph_proto == 2)
		{
			ihl = iph->ihl;
			ih = (struct igmphdr *)(pkt + ihl * 4);
			ih_type = ih->type;
		/*	ih = (struct igmphdr *)pkt;*/
			daddr = iph->daddr;       

		}
	#endif

	

	/*first we should check if the destination address is from
	*0xe0000002(PIM V1 HELLO) ,0xe0000004(DVMRP probes) ,0xe0000005(0xe0000006)(MOSPF messages)
	* 0xe000000d(PIM V2 hello)
	*/
/*addr = ntohl(iph->saddr);*/
/*THER_MAP_IP_MULTICAST(&saddr, saenaddr);       */
	#ifdef _FLEX_HAMMER_

		if ((daddr == 0xe0000002) || (daddr == 0xe0000004) ||(daddr == 0xe0000005) || \
			(daddr == 0xe0000006) ||(daddr == 0xe000000d ))
		{
			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
	#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;
			}
		}
	}
}


/***************************************************************************************************
*	Func:	igmp_snoop_pkt_process
*This function processes the received IGMP packet.
*Input:  msg - the msg received from msg queue 
*Output:OK  -the packet is normally processed
*	ERROR - meets error when processing the packet  	
****************************************************************************************************/

int igmp_snoop_pkt_process(TIMERMSG_S  *msg)
{
	/*how to get the igmphdr from the pkt, and if there is many igmp datagrams in the pkt,what to do*/
	/*unsigned char * buf;
	buf = (unsigned char *)kmalloc(len+2 , IGMP_SNOOPING_MOD_ID);
	if(NULL == buf)
		return NULL;
	memcpy(buf,&port_no,2);
	memcpy(buf+2,pkt,len);*/
	struct igmp_snoop_pkt_msg *rec_pkt_msg;
	struct iphdr *iph;
	struct igmphdr *ih;
	short port_no;
	char *vlanpkt,*pkt;
	short VID ,new_vid;
	int len, ihl ,check_rnet,res,res_vlan_index;
	long timer;
	int tag_flag = 0;
	unsigned int group_addr;
	unsigned char enaddr[6], saenaddr[6],daenaddr[6];
	__u32	daddr, saddr;
	struct vlanhdr *veth;
/*for 802.1q*/
	unsigned char vlanhdr_for_send[4] ,vid_tag_pad[4];   
	short ih_type;
	char iph_proto;
	struct igmp_snoop_group *igmp_snoop_group_to_join, *igmp_snoop_group_to_find;
	struct igmp_snoop_router_entry *igmp_snoop_router_to_find;
	struct igmp_snoop_mac_group *igmp_snoop_mac_to_find;
	rec_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
	port_no = rec_pkt_msg->port_no;
	vlanpkt = rec_pkt_msg->pkt;
	VID = rec_pkt_msg->VID;
	len = rec_pkt_msg->len;
	/*check if the dest macaddr and the group_addr and the dest ipaddr match*/
	check_rnet = igmp_pkt_check(vlanpkt,len);
	if (check_rnet != 0)
	{
		kfree(rec_pkt_msg);
		rec_pkt_msg = NULL;
		kfree(vlanpkt);
		vlanpkt = NULL;
		return;
	}		
	veth = (struct vlanhdr *)vlanpkt;
	memcpy((char*)saenaddr,(char*)(veth->v_source),ETH_ALEN);
	memcpy((unsigned char*)daenaddr,(unsigned char *)(veth->v_dest),ETH_ALEN);
	/*get the 802.1q*/
	memcpy((char*)vlanhdr_for_send, (char*)vlanpkt + ETH_ALEN*2 , 4);
	#ifdef _U_24_IGMPSNOOPING_
		vid_tag_pad[0] = 0x81;
		vid_tag_pad[1] = 0x00;
		if (! memcmp(vlanpkt + ETH_ALEN*2, vid_tag_pad,2) )
		{
			memcpy(vid_tag_pad + 2,vlanpkt + ETH_ALEN*2 +2 ,2);
			memcpy((char*)&new_vid,(char*)(vid_tag_pad+2),2);
			new_vid = ntohs(new_vid);
			new_vid &= 0x0fff;
			
			if ( -1 ==getvlanindexbyvid(new_vid))
			{
				kfree(rec_pkt_msg);
				rec_pkt_msg = NULL;
				kfree(vlanpkt);
				vlanpkt = NULL;
				return;
			}
			else
			{
				res_vlan_index = getvlanindexbyvid(new_vid);
				res = getportinfoinvlan(port_no,res_vlan_index);
				if (res == 0)
				{
					kfree(rec_pkt_msg);
					rec_pkt_msg = NULL;
					kfree(vlanpkt);
					vlanpkt = NULL;
					return;
				}
			}
			VID = new_vid;
			tag_flag = 1;
		}
	#endif
	/*before here,the vlanpkt includes the vlanhdr,now we change it to pkt*/

	len = len - sizeof(struct vlanhdr);
	pkt =  (char *)kmalloc(len , IGMP_SNOOPING_MOD_ID);
	if(NULL == pkt)
		return NULL;
	bzero ((char *)pkt, len);
	memcpy(pkt,vlanpkt + sizeof(struct vlanhdr),len);
	kfree(rec_pkt_msg->pkt);
	rec_pkt_msg->pkt = pkt;
	iph = (struct iphdr *)pkt;
	#ifdef _FLEX_HAMMER_
		iph_proto = ntohs(iph->protocol);
		if(iph_proto == 2)
		{
			ihl = ntohs(iph->ihl);
			ih = (struct igmphdr *)(pkt + ihl * 4);
			ih_type = ntohs(ih->type);
			daddr = ntohl(iph->daddr);       
		/*	ih = (struct igmphdr *)pkt;*/
		}

	#endif
	#ifdef _U_24_IGMPSNOOPING_
		iph_proto = iph->protocol;
		if(iph_proto == 2)
		{
			ihl = iph->ihl;
			ih = (struct igmphdr *)(pkt + ihl * 4);
			ih_type = ih->type;
		/*	ih = (struct igmphdr *)pkt;*/
			daddr = iph->daddr;       

		}
	#endif

	

	/*first we should check if the destination address is from
	*0xe0000002(PIM V1 HELLO) ,0xe0000004(DVMRP probes) ,0xe0000005(0xe0000006)(MOSPF messages)
	* 0xe000000d(PIM V2 hello)
	*/
/*addr = ntohl(iph->saddr);*/
/*THER_MAP_IP_MULTICAST(&saddr, saenaddr);       */
	#ifdef _FLEX_HAMMER_

		if ((daddr == 0xe0000002) || (daddr == 0xe0000004) ||(daddr == 0xe0000005) || \
			(daddr == 0xe0000006) ||(daddr == 0xe000000d ))
		{
			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

⌨️ 快捷键说明

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