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

📄 igmp_snoop.c

📁 harmmer-os的其中一个部分代码 。
💻 C
📖 第 1 页 / 共 5 页
字号:

/* Main routine of igmp_snoop. */
/***************************************************************************************************
*	Func:	igmp_snoop_main
*Main routine of igmp_snoop 	
****************************************************************************************************/

int igmp_snoop_main (int argc, char **argv)
{

	/*struct thread thread;*/
	/* Prepare master thread. */
/*	igmp_snoop_master = thread_make_master ();*/
/*    	thread_add_read (igmp_snoop_master, igmp_snoop_msg_read,NULL, (int)IgmpSnoopMsgQId);  why should i convert the IgmpSnoopMsgQId into int  */
/*
    thread_add_timer (igmp_snoop_master, igmp_snoop_update, NULL, 
			  (unsigned long)IgmpSnoopMsgQId ? 2 : update_timer);
			  */
/*semGive (semIgmpSnoopSyncCLI);     */

  /* Execute each thread. */
/*  	while (thread_fetch (igmp_snoop_master, &thread))
    	thread_call (&thread);  */

/*   Not reached. */
  /*	exit (0);*/
  int ret;
  TIMERMSG_S msgbuf;
  int fromlen, len;
  ROUTER_V1_TIME_OUT_TIMER = 400*1000;
  GROUP_MEMEBER_SHIP_INTERVAL =  260*1000;
  GROUP_V1_MEMEBER_SHIP_INTERVAL = 260*1000;
  ROUTER_TIME_OUT_TIMER = 260*1000;
  ROUTER_GENERAL_QUERY_INTERVAL = 125*1000;

  host_time_milli_flag = 1;
  router_time_milli_flag = 1;

 
  
/*  IgmpSnoopMsgQId = (MSG_Q_ID)THREAD_FD (t);  */
 
  /* Add myself to tne next event */
/*  thread_add_read(igmp_snoop_master, igmp_snoop_msg_read, NULL, (int)IgmpSnoopMsgQId);  */ /*here is the same as above*/
  
  memset (&msgbuf, 0, sizeof (TIMERMSG_S));
/*
  bzero ((char *)igmp_snoop_router_list, sizeof (struct igmp_snoop_router_entry));
  bzero ((char *)igmp_snoop_mac_list, sizeof (struct igmp_snoop_mac_group));
  */
/*  fromlen = sizeof(struct igmp_snoop_pkt_msg) ;*/
while(1)
{
	  len = msgQReceive(IgmpSnoopMsgQId, (char *)&msgbuf, sizeof(msgbuf), WAIT_FOREVER);
	 
	  if (len < 0) 
	  {
	     zlog_info ("msgQReceive failed: %s", strerror (errno));
	  }
	  else
      {
		   igmp_snoop_process_msg(&msgbuf);
	  }
}

 	/*process the received msg*/
 /*igmp_snoop_process_msg(&msgbuf);*/

}


/***************************************************************************************************
*	Func:	igmp_snoop_msg_read()
*This function  reads the messages from the msg queue.
*Input:
*Output:OK  -the packet is normally disposed
*	ERROR - meets error when processing the packet
****************************************************************************************************/

int igmp_snoop_msg_read(struct thread *t)
{
  int ret;
  TIMERMSG_S msgbuf;
  int fromlen, len;
 
  
  IgmpSnoopMsgQId = (MSG_Q_ID)THREAD_FD (t);  
 
  /* Add myself to tne next event */
  thread_add_read(igmp_snoop_master, igmp_snoop_msg_read, NULL, (int)IgmpSnoopMsgQId);  /*here is the same as above*/
  
  memset (&msgbuf, 0, sizeof (TIMERMSG_S));
  fromlen = sizeof(struct igmp_snoop_pkt_msg);
  len = msgQReceive(IgmpSnoopMsgQId, (char *)&msgbuf, sizeof(msgbuf), WAIT_FOREVER);
 
  if (len < 0) 
  {
     zlog_info ("msgQReceive failed: %s", strerror (errno));
     return len;
  }

 	/*process the received msg*/
 igmp_snoop_process_msg(&msgbuf);

}




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



 int igmp_snoop_process_msg_false(TIMERMSG_S *msg)
{
	struct igmp_snoop_pkt_msg *igmp_rec_pkt_msg;
	char *vlanpkt;
	igmp_rec_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
	switch (msg->source_id)
	{
		case TASK_TIMER_NOTIFY:
			
			switch(igmp_rec_pkt_msg->time_out_type)
			{
				case ROUTER_TIME_OUT:
					kfree(igmp_rec_pkt_msg);
					break;
				case GROUP_TIME_OUT:
					kfree(igmp_rec_pkt_msg);
					break;
				case ROUTER_V1_TIME_OUT:
					kfree(igmp_rec_pkt_msg);
					break;
				case GROUP_V1_TIME_OUT:            /*the igmpv1 host of the group is timeout*/
					kfree(igmp_rec_pkt_msg);
					break;
				case OTHER_ROUTER_TIME_OUT:
					kfree(igmp_rec_pkt_msg);
					break;
				case GENERAL_QEURY_10S_TIMEOUT:  /* the every timer(10s) for group */
					kfree(igmp_rec_pkt_msg);
 					break;
			}
			break;
		case IGMP_SNOOP_RECV_PKT:
			vlanpkt = igmp_rec_pkt_msg->pkt;
			kfree(igmp_rec_pkt_msg);
			kfree(vlanpkt);

			break;
		default:
			syslog(LOG_INFO,"there is error with the msg");
			break;
	}
}



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



 int igmp_snoop_process_msg(TIMERMSG_S *msg)
{
	struct igmp_snoop_pkt_msg *igmp_rec_pkt_msg;
	igmp_rec_pkt_msg = (struct igmp_snoop_pkt_msg *)msg->parg;
	switch (msg->source_id)
	{
		case TASK_TIMER_NOTIFY:
			
			switch(igmp_rec_pkt_msg->time_out_type)
			{
				case ROUTER_TIME_OUT:
					router_port_timeout_process(msg);
					break;
				case GROUP_TIME_OUT:
					group_port_timeout_process(msg);
					break;
				case ROUTER_V1_TIME_OUT:
					router_v1_timeout_process(msg);
					break;
				case GROUP_V1_TIME_OUT:            /*the igmpv1 host of the group is timeout*/
					group_v1_timeout_process(msg);
					break;
				case OTHER_ROUTER_TIME_OUT:
					other_router_port_timeout_process(msg);
					break;
				case GENERAL_QEURY_10S_TIMEOUT:  /* the every timer(10s) for group */
					 general_query_10s_timeout_process(msg);
 					break;
			}
			break;
		case IGMP_SNOOP_RECV_PKT:
			#ifdef _FLEX_HAMMER_
				igmp_snoop_pkt_process_flex(msg);
			#endif
			#ifdef _U_24_IGMPSNOOPING_
				igmp_snoop_pkt_process(msg);
			#endif
			break;
		default:
			syslog(LOG_INFO,"there is error with the msg");
			break;
	}
}

void u24_recv_igmp(unsigned short portno,unsigned char* pkt,int len)
{


}
/***************************************************************************************************
*	Func:	igmp_snoop_recv
*This function is called by the lower function when it received a pkt. this function just 
*       makes a copy for the pkt ,and send msg to the msgqueque.
*Input: port_no  - the port_no from which received this packet
*	pkt   -	  the received packet
* 	len   -   the length of the packet
*   VID  -   the vlan id to which the port_no belongs
*Output:OK  -the packet is normally processed
*	ERROR - meets error when processing the packet  	
****************************************************************************************************/

int igmp_snoop_recv(int port_no, char *pkt, int len, int VID)
{
	unsigned char *pktbuf;
	struct igmp_snoop_pkt_msg * rec_pkt_msg;
	TIMERMSG_S  * msg;
	int rnet,msg_num;
	if (igmp_snoop_tid == 0 )
		return;
	msg_num = msgQNumMsgs(IgmpSnoopMsgQId);
	if(12 <= msg_num )
		return;
   	msg = (TIMERMSG_S  *)kmalloc(sizeof(TIMERMSG_S) , IGMP_SNOOPING_MOD_ID);
	if(NULL == msg)
		return NULL;
	bzero ((char *)msg, sizeof (TIMERMSG_S));
	rec_pkt_msg = (struct igmp_snoop_pkt_msg *)kmalloc(sizeof(struct igmp_snoop_pkt_msg) , IGMP_SNOOPING_MOD_ID);
	if(NULL == rec_pkt_msg)
		return NULL;
	bzero ((char *)rec_pkt_msg, sizeof (struct igmp_snoop_pkt_msg));
	pktbuf = (unsigned char *)kmalloc(len , IGMP_SNOOPING_MOD_ID);
	if(NULL == pktbuf)
		return NULL;
	bzero ((char *)pktbuf, len);
	memcpy(pktbuf,pkt,len);
	/*memcpy(pktbuf+2,pkt,len);*/
	rec_pkt_msg->port_no = port_no;
	rec_pkt_msg->len = len;
	rec_pkt_msg->pkt = pktbuf;
	rec_pkt_msg->VID = VID;

	msg->source_id = IGMP_SNOOP_RECV_PKT;
	msg->timer_id = 0;   /*should choose an impossible value temporarily 0*/
	msg->func = 0;
	msg->parg = (char *)rec_pkt_msg;
 	rnet = (int)msgQSend(IgmpSnoopMsgQId, (char *)msg, sizeof(TIMERMSG_S), NO_WAIT, MSG_PRI_NORMAL);
 	kfree(msg);
	msg = NULL;
	if (rnet ==0 )
 	{	syslog(LOG_INFO,"return ok");
		return OK;
	}
 	else
	{
 		syslog(LOG_INFO, "return error");
 		kfree(pktbuf);
		pktbuf = NULL;
 		kfree(rec_pkt_msg);
 		rec_pkt_msg = NULL;
 		return ERROR;
 	}
/*	kfree(rec_pkt_msg);
	rec_pkt_msg = NULL;*/

	/*kfree(pktbuf);
	pktbuf = NULL;*/
}




/***************************************************************************************************
*	Func:	igmp_snoop_pkt_process_flex
*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_flex(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;
	struct _vlanentry * vlan_for_new_vid;
/*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_flex(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);
	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;
		vlan_for_new_vid = vlan_get_by_VID(new_vid);
		if ( NULL == vlan_for_new_vid)
		{
			kfree(rec_pkt_msg);
			rec_pkt_msg = NULL;
			kfree(vlanpkt);
			vlanpkt = NULL;
			return;
		}
		else
		{
			res = vlan_port_relation(port_no,vlan_for_new_vid);
			if (res == 0)
			{
				kfree(rec_pkt_msg);
				rec_pkt_msg = NULL;
				kfree(vlanpkt);
				vlanpkt = NULL;
				return;
			}
		}
		VID = new_vid;
		tag_flag = 1;
	}
	
	/*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);

⌨️ 快捷键说明

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