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

📄 myigmp.c

📁 一个基于linux的TCP/IP协议栈的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (reporter)				myigmp_send_report(in_dev, im, IGMP_HOST_LEAVE_MESSAGE);			goto done;		}		myigmpv3_add_delrec(in_dev, im);		myigmp_ifc_event(in_dev);	}done:#endif	myip_mc_clear_src(im);}static void myigmp_group_added(struct ip_mc_list *im){	struct in_device *in_dev = im->interface;	if( im->loaded == 0 ){		im->loaded = 1; 		myip_mc_filter_add(in_dev, im->multiaddr);	}#ifdef CONFIG_IP_MULTICAST	if (im->multiaddr == IGMP_ALL_HOSTS)		return;	if (in_dev->dead)		return;	if( MYIGMP_V1_SEEN(in_dev) || MYIGMP_V2_SEEN(in_dev) ){		spin_lock_bh(&im->lock);		myigmp_start_timer(im, MYIGMP_Initial_Report_Delay);		spin_unlock_bh(&im->lock);		return;	}	im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv :		MYIGMP_Unsolicited_Report_Count;	myigmp_ifc_event( in_dev );#endif}void myip_mc_inc_group(struct in_device *in_dev, u32 addr){	struct ip_mc_list *im;	int i;	ASSERT_RTNL();	for (im=in_dev->mc_list; im; im=im->next) {		if (im->multiaddr == addr) {			im->users++;			i = myip_mc_add_src(in_dev, &addr, MCAST_EXCLUDE, 0, NULL, 0);			goto out;		}	}	im = kmalloc(sizeof(*im), GFP_KERNEL);	if (!im)		goto out;	im->users=1;	im->interface=in_dev;	in_dev_hold(in_dev);	im->multiaddr=addr;	im->sfmode = MCAST_EXCLUDE;	im->sfcount[MCAST_INCLUDE] = 0;	im->sfcount[MCAST_EXCLUDE] = 1;	im->sources = NULL;	im->tomb = NULL;	im->crcount = 0;	atomic_set(&im->refcnt, 1);	spin_lock_init(&im->lock);#ifdef CONFIG_IP_MULTICAST	im->tm_running=0;	init_timer(&im->timer);	im->timer.data=(unsigned long)im;	im->timer.function=&myigmp_timer_expire;	im->unsolicit_count = MYIGMP_Unsolicited_Report_Count;	im->reporter = 0;	im->gsquery = 0;#endif	im->loaded = 0;	write_lock_bh(&in_dev->mc_list_lock);	im->next=in_dev->mc_list;	in_dev->mc_list=im;	write_unlock_bh(&in_dev->mc_list_lock);#ifdef CONFIG_IP_MULTICAST	myigmpv3_del_delrec(in_dev, im->multiaddr);#endif	myigmp_group_added(im);	if (!in_dev->dead)		myip_rt_multicast_event(in_dev);out:	return;}void myip_mc_dec_group(struct in_device *in_dev, u32 addr){	struct ip_mc_list *i, **ip;		ASSERT_RTNL();		for( ip=&in_dev->mc_list; (i=*ip)!=NULL; ip=&i->next ){		if (i->multiaddr==addr) {			if (--i->users == 0) {				write_lock_bh(&in_dev->mc_list_lock);				*ip = i->next;				write_unlock_bh(&in_dev->mc_list_lock);				myigmp_group_dropped(i);				if (!in_dev->dead)					myip_rt_multicast_event(in_dev);				myip_ma_put(i);				return;			}			break;		}	}}void myip_mc_down(struct in_device *in_dev){}void myip_mc_up(struct in_device *in_dev){	struct ip_mc_list *i;	ASSERT_RTNL();	myip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);	for (i=in_dev->mc_list; i; i=i->next)		myigmp_group_added(i);}static void myigmp_ifc_timer_expire(unsigned long data){}static void myigmp_gq_timer_expire(unsigned long data){/*	struct in_device *in_dev = (struct in_device *)data;	in_dev->mr_gq_running = 0;	igmpv3_send_report(in_dev, NULL);	__in_dev_put(in_dev);*/}static struct in_device * myip_mc_find_dev(struct ip_mreqn *imr){	struct flowi fl = { .nl_u = { .ip4_u =				      { .daddr = imr->imr_multiaddr.s_addr } } };	struct rtable *rt;	struct net_device *dev = NULL;	struct in_device *idev = NULL;	if( imr->imr_ifindex ){		idev = inetdev_by_index(imr->imr_ifindex);		if (idev)			__in_dev_put(idev);		return idev;	}	if( imr->imr_address.s_addr ){		dev = myip_dev_find(imr->imr_address.s_addr);		if (!dev)			return NULL;		__dev_put(dev);	}	if( !dev && !myip_route_output_key(&rt, &fl) ){		dev = rt->u.dst.dev;		ip_rt_put(rt);	}	if( dev ){		imr->imr_ifindex = dev->ifindex;		idev = __in_dev_get_rtnl(dev);	}	return idev;}static int myip_mc_del_src(struct in_device *in_dev, __u32 *pmca, int sfmode,				int sfcount, __u32 *psfsrc, int delta){	struct ip_mc_list *pmc;	int	changerec = 0;	int	i, err;	if (!in_dev)		return -ENODEV;	read_lock(&in_dev->mc_list_lock);	for (pmc=in_dev->mc_list; pmc; pmc=pmc->next) {		if (*pmca == pmc->multiaddr)			break;	}	if (!pmc) {		read_unlock(&in_dev->mc_list_lock);		return -ESRCH;	}	spin_lock_bh(&pmc->lock);	read_unlock(&in_dev->mc_list_lock);#ifdef CONFIG_IP_MULTICAST	mysf_markstate(pmc);#endif	if (!delta) {		err = -EINVAL;		if (!pmc->sfcount[sfmode])			goto out_unlock;		pmc->sfcount[sfmode]--;	}	err = 0;	for (i=0; i<sfcount; i++) {		int rv = myip_mc_del1_src(pmc, sfmode, &psfsrc[i]);		changerec |= rv > 0;		if (!err && rv < 0)			err = rv;	}	if( pmc->sfmode == MCAST_EXCLUDE && pmc->sfcount[MCAST_EXCLUDE] == 0 &&					pmc->sfcount[MCAST_INCLUDE] ){#ifdef CONFIG_IP_MULTICAST		struct ip_sf_list *psf;#endif		pmc->sfmode = MCAST_INCLUDE;#ifdef CONFIG_IP_MULTICAST		pmc->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : 			MYIGMP_Unsolicited_Report_Count;		in_dev->mr_ifc_count = pmc->crcount;		for (psf=pmc->sources; psf; psf = psf->sf_next)			psf->sf_crcount = 0;		myigmp_ifc_event(pmc->interface);	}else if( mysf_setstate(pmc) || changerec ){		myigmp_ifc_event(pmc->interface);#endif	}out_unlock:	spin_unlock_bh(&pmc->lock);	return err;}static int myip_mc_leave_src(struct sock *sk, struct ip_mc_socklist *iml,				struct in_device *in_dev){	int err;	if (iml->sflist == 0) {		return myip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr,						iml->sfmode, 0, NULL, 0);	}	err = myip_mc_del_src(in_dev, &iml->multi.imr_multiaddr.s_addr,					iml->sfmode, iml->sflist->sl_count,					iml->sflist->sl_addr, 0);	sock_kfree_s( sk, iml->sflist, IP_SFLSIZE(iml->sflist->sl_max) );	iml->sflist = NULL;	return err;}int myip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr){	struct inet_sock *inet = inet_sk(sk);	struct ip_mc_socklist *iml, **imlp;	struct in_device *in_dev;	u32 group = imr->imr_multiaddr.s_addr;	u32 ifindex;	rtnl_lock();	in_dev = myip_mc_find_dev(imr);	if (!in_dev) {		rtnl_unlock();		return -ENODEV;	}	ifindex = imr->imr_ifindex;	for (imlp = &inet->mc_list; (iml = *imlp) != NULL; imlp = &iml->next) {		if (iml->multi.imr_multiaddr.s_addr == group &&		    iml->multi.imr_ifindex == ifindex) {			(void)myip_mc_leave_src(sk, iml, in_dev);			*imlp = iml->next;			myip_mc_dec_group(in_dev, group);			rtnl_unlock();			sock_kfree_s(sk, iml, sizeof(*iml));			return 0;		}	}	rtnl_unlock();	return -EADDRNOTAVAIL;}int myip_mc_join_group(struct sock *sk , struct ip_mreqn *imr){	int err;	u32 addr = imr->imr_multiaddr.s_addr;	struct ip_mc_socklist *iml=NULL, *i;	struct in_device *in_dev;	struct inet_sock *inet = inet_sk(sk);	int ifindex;	int count = 0;	if (!MULTICAST(addr))		return -EINVAL;	rtnl_shlock();	in_dev = myip_mc_find_dev(imr);	if (!in_dev) {		iml = NULL;		err = -ENODEV;		goto done;	}	err = -EADDRINUSE;	ifindex = imr->imr_ifindex;	for( i = inet->mc_list; i; i = i->next ){		if (i->multi.imr_multiaddr.s_addr == addr &&						i->multi.imr_ifindex == ifindex)			goto done;		count++;	}	err = -ENOBUFS;	if (count >= sysctl_igmp_max_memberships)		goto done;	iml = sock_kmalloc(sk,sizeof(*iml),GFP_KERNEL);	if (iml == NULL)		goto done;	memcpy(&iml->multi, imr, sizeof(*imr));	iml->next = inet->mc_list;	iml->sflist = NULL;	iml->sfmode = MCAST_EXCLUDE;	inet->mc_list = iml;	myip_mc_inc_group(in_dev, addr);	err = 0;done:	rtnl_shunlock();	return err;}void myip_mc_init_dev(struct in_device *in_dev){	ASSERT_RTNL();	in_dev->mc_tomb = NULL;#ifdef CONFIG_IP_MULTICAST	in_dev->mr_gq_running = 0;	init_timer(&in_dev->mr_gq_timer);	in_dev->mr_gq_timer.data=(unsigned long) in_dev;	in_dev->mr_gq_timer.function=&myigmp_gq_timer_expire;	in_dev->mr_ifc_count = 0;	init_timer(&in_dev->mr_ifc_timer);	in_dev->mr_ifc_timer.data=(unsigned long) in_dev;	in_dev->mr_ifc_timer.function=&myigmp_ifc_timer_expire;	in_dev->mr_qrv = MYIGMP_Unsolicited_Report_Count;#endif	rwlock_init(&in_dev->mc_list_lock);	spin_lock_init(&in_dev->mc_tomb_lock);}int myigmp_rcv(struct sk_buff *skb){	return 0;}void myip_mc_drop_socket(struct sock *sk){}static int myigmp_mc_seq_open(struct inode *inode, struct file *file){	return 0;}static struct file_operations myigmp_mc_seq_fops = {	.owner		=	THIS_MODULE,	.open		=	myigmp_mc_seq_open,	.read		=	seq_read,	.llseek		=	seq_lseek,	.release	=	seq_release_private,};static int myigmp_mcf_seq_open(struct inode *inode, struct file *file){	return 0;}static struct file_operations myigmp_mcf_seq_fops = {	.owner		=	THIS_MODULE,	.open		=	myigmp_mcf_seq_open,	.read		=	seq_read,	.llseek		=	seq_lseek,	.release	=	seq_release_private,};int __init myigmp_mc_proc_init(void){	proc_net_fops_create("myigmp", S_IRUGO, &myigmp_mc_seq_fops);	proc_net_fops_create("mymcfilter", S_IRUGO, &myigmp_mcf_seq_fops);	return 0;}void __exit myigmp_mc_proc_exit(void){	remove_proc_entry("myigmp", proc_net );	remove_proc_entry("mymcfilter", proc_net );}

⌨️ 快捷键说明

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