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

📄 igmp.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (arp_mc_map(addr, buf, dev, 0) == 0)		dev_mc_add(dev,buf,dev->addr_len,0);}/* *	Remove a filter from a device */static void ip_mc_filter_del(struct in_device *in_dev, u32 addr){	char buf[MAX_ADDR_LEN];	struct net_device *dev = in_dev->dev;	if (arp_mc_map(addr, buf, dev, 0) == 0)		dev_mc_delete(dev,buf,dev->addr_len,0);}static void igmp_group_dropped(struct ip_mc_list *im){#ifdef CONFIG_IP_MULTICAST	int reporter;#endif	if (im->loaded) {		im->loaded = 0;		ip_mc_filter_del(im->interface, im->multiaddr);	}#ifdef CONFIG_IP_MULTICAST	if (im->multiaddr == IGMP_ALL_HOSTS)		return;	reporter = im->reporter;	igmp_stop_timer(im);	if (reporter && !IGMP_V1_SEEN(im->interface))		igmp_send_report(im->interface->dev, im->multiaddr, IGMP_HOST_LEAVE_MESSAGE);#endif}static void igmp_group_added(struct ip_mc_list *im){	if (im->loaded == 0) {		im->loaded = 1;		ip_mc_filter_add(im->interface, im->multiaddr);	}#ifdef CONFIG_IP_MULTICAST	if (im->multiaddr == IGMP_ALL_HOSTS)		return;	spin_lock_bh(&im->lock);	igmp_start_timer(im, IGMP_Initial_Report_Delay);	spin_unlock_bh(&im->lock);#endif}/* *	Multicast list managers *//* *	A socket has joined a multicast group on device dev. */void ip_mc_inc_group(struct in_device *in_dev, u32 addr){	struct ip_mc_list *im;	ASSERT_RTNL();	for (im=in_dev->mc_list; im; im=im->next) {		if (im->multiaddr == addr) {			im->users++;			goto out;		}	}	im = (struct ip_mc_list *)kmalloc(sizeof(*im), GFP_KERNEL);	if (!im)		goto out;	im->users=1;	im->interface=in_dev;	in_dev_hold(in_dev);	im->multiaddr=addr;	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=&igmp_timer_expire;	im->unsolicit_count = IGMP_Unsolicited_Report_Count;	im->reporter = 0;#endif	im->loaded = 0;	write_lock_bh(&in_dev->lock);	im->next=in_dev->mc_list;	in_dev->mc_list=im;	write_unlock_bh(&in_dev->lock);	igmp_group_added(im);	if (in_dev->dev->flags & IFF_UP)		ip_rt_multicast_event(in_dev);out:	return;}/* *	A socket has left a multicast group on device dev */int ip_mc_dec_group(struct in_device *in_dev, u32 addr){	int err = -ESRCH;	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->lock);				*ip = i->next;				write_unlock_bh(&in_dev->lock);				igmp_group_dropped(i);				if (in_dev->dev->flags & IFF_UP)					ip_rt_multicast_event(in_dev);				ip_ma_put(i);				return 0;			}			err = 0;			break;		}	}	return -ESRCH;}/* Device going down */void ip_mc_down(struct in_device *in_dev){	struct ip_mc_list *i;	ASSERT_RTNL();	for (i=in_dev->mc_list; i; i=i->next)		igmp_group_dropped(i);	ip_mc_dec_group(in_dev, IGMP_ALL_HOSTS);}/* Device going up */void ip_mc_up(struct in_device *in_dev){	struct ip_mc_list *i;	ASSERT_RTNL();	ip_mc_inc_group(in_dev, IGMP_ALL_HOSTS);	for (i=in_dev->mc_list; i; i=i->next)		igmp_group_added(i);}/* *	Device is about to be destroyed: clean up. */void ip_mc_destroy_dev(struct in_device *in_dev){	struct ip_mc_list *i;	ASSERT_RTNL();	write_lock_bh(&in_dev->lock);	while ((i = in_dev->mc_list) != NULL) {		in_dev->mc_list = i->next;		write_unlock_bh(&in_dev->lock);		igmp_group_dropped(i);		ip_ma_put(i);		write_lock_bh(&in_dev->lock);	}	write_unlock_bh(&in_dev->lock);}static struct in_device * ip_mc_find_dev(struct ip_mreqn *imr){	struct rtable *rt;	struct net_device *dev = NULL;	struct in_device *idev = NULL;	if (imr->imr_address.s_addr) {		dev = ip_dev_find(imr->imr_address.s_addr);		if (!dev)			return NULL;		__dev_put(dev);	}	if (!dev && !ip_route_output(&rt, imr->imr_multiaddr.s_addr, 0, 0, 0)) {		dev = rt->u.dst.dev;		ip_rt_put(rt);	}	if (dev) {		imr->imr_ifindex = dev->ifindex;		idev = __in_dev_get(dev);	}	return idev;}/* *	Join a socket to a group */int sysctl_igmp_max_memberships = IP_MAX_MEMBERSHIPS;int ip_mc_join_group(struct sock *sk , struct ip_mreqn *imr){	int err;	u32 addr = imr->imr_multiaddr.s_addr;	struct ip_mc_socklist *iml, *i;	struct in_device *in_dev;	int count = 0;	if (!MULTICAST(addr))		return -EINVAL;	rtnl_shlock();	if (!imr->imr_ifindex)		in_dev = ip_mc_find_dev(imr);	else {		in_dev = inetdev_by_index(imr->imr_ifindex);		if (in_dev)			__in_dev_put(in_dev);	}	if (!in_dev) {		iml = NULL;		err = -ENODEV;		goto done;	}	iml = (struct ip_mc_socklist *)sock_kmalloc(sk, sizeof(*iml), GFP_KERNEL);	err = -EADDRINUSE;	for (i=sk->protinfo.af_inet.mc_list; i; i=i->next) {		if (memcmp(&i->multi, imr, sizeof(*imr)) == 0) {			/* New style additions are reference counted */			if (imr->imr_address.s_addr == 0) {				i->count++;				err = 0;			}			goto done;		}		count++;	}	err = -ENOBUFS;	if (iml == NULL || count >= sysctl_igmp_max_memberships)		goto done;	memcpy(&iml->multi, imr, sizeof(*imr));	iml->next = sk->protinfo.af_inet.mc_list;	iml->count = 1;	sk->protinfo.af_inet.mc_list = iml;	ip_mc_inc_group(in_dev, addr);	iml = NULL;	err = 0;done:	rtnl_shunlock();	if (iml)		sock_kfree_s(sk, iml, sizeof(*iml));	return err;}/* *	Ask a socket to leave a group. */int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr){	struct ip_mc_socklist *iml, **imlp;	rtnl_lock();	for (imlp=&sk->protinfo.af_inet.mc_list; (iml=*imlp)!=NULL; imlp=&iml->next) {		if (iml->multi.imr_multiaddr.s_addr==imr->imr_multiaddr.s_addr &&		    iml->multi.imr_address.s_addr==imr->imr_address.s_addr &&		    (!imr->imr_ifindex || iml->multi.imr_ifindex==imr->imr_ifindex)) {			struct in_device *in_dev;			if (--iml->count) {				rtnl_unlock();				return 0;			}			*imlp = iml->next;			in_dev = inetdev_by_index(iml->multi.imr_ifindex);			if (in_dev) {				ip_mc_dec_group(in_dev, imr->imr_multiaddr.s_addr);				in_dev_put(in_dev);			}			rtnl_unlock();			sock_kfree_s(sk, iml, sizeof(*iml));			return 0;		}	}	rtnl_unlock();	return -EADDRNOTAVAIL;}/* *	A socket is closing. */void ip_mc_drop_socket(struct sock *sk){	struct ip_mc_socklist *iml;	if (sk->protinfo.af_inet.mc_list == NULL)		return;	rtnl_lock();	while ((iml=sk->protinfo.af_inet.mc_list) != NULL) {		struct in_device *in_dev;		sk->protinfo.af_inet.mc_list = iml->next;		if ((in_dev = inetdev_by_index(iml->multi.imr_ifindex)) != NULL) {			ip_mc_dec_group(in_dev, iml->multi.imr_multiaddr.s_addr);			in_dev_put(in_dev);		}		sock_kfree_s(sk, iml, sizeof(*iml));	}	rtnl_unlock();}int ip_check_mc(struct in_device *in_dev, u32 mc_addr){	struct ip_mc_list *im;	read_lock(&in_dev->lock);	for (im=in_dev->mc_list; im; im=im->next) {		if (im->multiaddr == mc_addr) {			read_unlock(&in_dev->lock);			return 1;		}	}	read_unlock(&in_dev->lock);	return 0;}#ifdef CONFIG_IP_MULTICAST int ip_mc_procinfo(char *buffer, char **start, off_t offset, int length){	off_t pos=0, begin=0;	struct ip_mc_list *im;	int len=0;	struct net_device *dev;	len=sprintf(buffer,"Idx\tDevice    : Count Querier\tGroup    Users Timer\tReporter\n");  	read_lock(&dev_base_lock);	for(dev = dev_base; dev; dev = dev->next) {		struct in_device *in_dev = in_dev_get(dev);		char   *querier = "NONE";		if (in_dev == NULL)			continue;		querier = IGMP_V1_SEEN(in_dev) ? "V1" : "V2";		len+=sprintf(buffer+len,"%d\t%-10s: %5d %7s\n",			     dev->ifindex, dev->name, dev->mc_count, querier);		read_lock(&in_dev->lock);		for (im = in_dev->mc_list; im; im = im->next) {			len+=sprintf(buffer+len,				     "\t\t\t\t%08lX %5d %d:%08lX\t\t%d\n",				     im->multiaddr, im->users,				     im->tm_running, im->timer.expires-jiffies, im->reporter);			pos=begin+len;			if(pos<offset)			{				len=0;				begin=pos;			}			if(pos>offset+length) {				read_unlock(&in_dev->lock);				in_dev_put(in_dev);				goto done;			}		}		read_unlock(&in_dev->lock);		in_dev_put(in_dev);	}done:	read_unlock(&dev_base_lock);	*start=buffer+(offset-begin);	len-=(offset-begin);	if(len>length)		len=length;	if(len<0)		len=0;	return len;}#endif

⌨️ 快捷键说明

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