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

📄 af_inet6.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 2 页
字号:
		sock_kfree_s(sk, opt, opt->tot_len);	return 0;}/* *	This does both peername and sockname. */ static int inet6_getname(struct socket *sock, struct sockaddr *uaddr,		 int *uaddr_len, int peer){	struct sockaddr_in6 *sin=(struct sockaddr_in6 *)uaddr;	struct sock *sk = sock->sk;  	sin->sin6_family = AF_INET6;	sin->sin6_flowinfo = 0;	sin->sin6_scope_id = 0;	if (peer) {		if (!sk->dport)			return -ENOTCONN;		if (((1<<sk->state)&(TCPF_CLOSE|TCPF_SYN_SENT)) && peer == 1)			return -ENOTCONN;		sin->sin6_port = sk->dport;		memcpy(&sin->sin6_addr, &sk->net_pinfo.af_inet6.daddr,		       sizeof(struct in6_addr));		if (sk->net_pinfo.af_inet6.sndflow)			sin->sin6_flowinfo = sk->net_pinfo.af_inet6.flow_label;	} else {		if (ipv6_addr_type(&sk->net_pinfo.af_inet6.rcv_saddr) == IPV6_ADDR_ANY)			memcpy(&sin->sin6_addr, 			       &sk->net_pinfo.af_inet6.saddr,			       sizeof(struct in6_addr));		else			memcpy(&sin->sin6_addr, 			       &sk->net_pinfo.af_inet6.rcv_saddr,			       sizeof(struct in6_addr));		sin->sin6_port = sk->sport;	}	if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)		sin->sin6_scope_id = sk->bound_dev_if;	*uaddr_len = sizeof(*sin);	return(0);}static int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg){	struct sock *sk = sock->sk;	int err = -EINVAL;	int pid;	switch(cmd) 	{	case FIOSETOWN:	case SIOCSPGRP:		if (get_user(pid, (int *) arg))			return -EFAULT;		/* see sock_no_fcntl */		if (current->pid != pid && current->pgrp != -pid && 		    !capable(CAP_NET_ADMIN))			return -EPERM;		sk->proc = pid;		return(0);	case FIOGETOWN:	case SIOCGPGRP:		return put_user(sk->proc,(int *)arg);	case SIOCGSTAMP:		if(sk->stamp.tv_sec==0)			return -ENOENT;		err = copy_to_user((void *)arg, &sk->stamp,				   sizeof(struct timeval));		if (err)			return -EFAULT;		return 0;	case SIOCADDRT:	case SIOCDELRT:	  		return(ipv6_route_ioctl(cmd,(void *)arg));	case SIOCSIFADDR:		return addrconf_add_ifaddr((void *) arg);	case SIOCDIFADDR:		return addrconf_del_ifaddr((void *) arg);	case SIOCSIFDSTADDR:		return addrconf_set_dstaddr((void *) arg);	default:		if ((cmd >= SIOCDEVPRIVATE) &&		    (cmd <= (SIOCDEVPRIVATE + 15)))			return(dev_ioctl(cmd,(void *) arg));				if(sk->prot->ioctl==0 || (err=sk->prot->ioctl(sk, cmd, arg))==-ENOIOCTLCMD)			return(dev_ioctl(cmd,(void *) arg));				return err;	}	/*NOTREACHED*/	return(0);}struct proto_ops inet6_stream_ops = {	family:		PF_INET6,	release:	inet6_release,	bind:		inet6_bind,	connect:	inet_stream_connect,		/* ok		*/	socketpair:	sock_no_socketpair,		/* a do nothing	*/	accept:		inet_accept,			/* ok		*/	getname:	inet6_getname, 	poll:		tcp_poll,			/* ok		*/	ioctl:		inet6_ioctl,			/* must change  */	listen:		inet_listen,			/* ok		*/	shutdown:	inet_shutdown,			/* ok		*/	setsockopt:	inet_setsockopt,		/* ok		*/	getsockopt:	inet_getsockopt,		/* ok		*/	sendmsg:	inet_sendmsg,			/* ok		*/	recvmsg:	inet_recvmsg,			/* ok		*/	mmap:		sock_no_mmap,	sendpage:	tcp_sendpage};struct proto_ops inet6_dgram_ops = {	family:		PF_INET6,	release:	inet6_release,	bind:		inet6_bind,	connect:	inet_dgram_connect,		/* ok		*/	socketpair:	sock_no_socketpair,		/* a do nothing	*/	accept:		sock_no_accept,			/* a do nothing	*/	getname:	inet6_getname, 	poll:		datagram_poll,			/* ok		*/	ioctl:		inet6_ioctl,			/* must change  */	listen:		sock_no_listen,			/* ok		*/	shutdown:	inet_shutdown,			/* ok		*/	setsockopt:	inet_setsockopt,		/* ok		*/	getsockopt:	inet_getsockopt,		/* ok		*/	sendmsg:	inet_sendmsg,			/* ok		*/	recvmsg:	inet_recvmsg,			/* ok		*/	mmap:		sock_no_mmap,	sendpage:	sock_no_sendpage,};struct net_proto_family inet6_family_ops = {	PF_INET6,	inet6_create};#ifdef MODULEint ipv6_unload(void){	if (!unloadable) return 1;	/* We keep internally 3 raw sockets */	return atomic_read(&(__this_module.uc.usecount)) - 3;}#endif#if defined(MODULE) && defined(CONFIG_SYSCTL)extern void ipv6_sysctl_register(void);extern void ipv6_sysctl_unregister(void);#endifstatic struct inet_protosw rawv6_protosw = {	type:        SOCK_RAW,	protocol:    IPPROTO_IP,	/* wild card */	prot:        &rawv6_prot,	ops:         &inet6_dgram_ops,	capability:  CAP_NET_RAW,	no_check:    UDP_CSUM_DEFAULT,	flags:       INET_PROTOSW_REUSE,};#define INETSW6_ARRAY_LEN (sizeof(inetsw6_array) / sizeof(struct inet_protosw))voidinet6_register_protosw(struct inet_protosw *p){	struct list_head *lh;	struct inet_protosw *answer;	int protocol = p->protocol;	br_write_lock_bh(BR_NETPROTO_LOCK);	if (p->type > SOCK_MAX)		goto out_illegal;	/* If we are trying to override a permanent protocol, bail. */	answer = NULL;	list_for_each(lh, &inetsw6[p->type]) {		answer = list_entry(lh, struct inet_protosw, list);		/* Check only the non-wild match. */		if (protocol == answer->protocol &&		    (INET_PROTOSW_PERMANENT & answer->flags))			break;		answer = NULL;	}	if (answer)		goto out_permanent;	/* Add to the BEGINNING so that we override any existing	 * entry.  This means that when we remove this entry, the	 * system automatically returns to the old behavior.	 */	list_add(&p->list, &inetsw6[p->type]);out:	br_write_unlock_bh(BR_NETPROTO_LOCK);	return;out_permanent:	printk(KERN_ERR "Attempt to override permanent protocol %d.\n",	       protocol);	goto out;out_illegal:	printk(KERN_ERR	       "Ignoring attempt to register illegal socket type %d.\n",	       p->type);	goto out;}voidinet6_unregister_protosw(struct inet_protosw *p){	inet_unregister_protosw(p);}static int __init inet6_init(void){	struct sk_buff *dummy_skb;        struct list_head *r;	int err;#ifdef MODULE	if (!mod_member_present(&__this_module, can_unload))	  return -EINVAL;	__this_module.can_unload = &ipv6_unload;#endif	printk(KERN_INFO "IPv6 v0.8 for NET4.0\n");	if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))	{		printk(KERN_CRIT "inet6_proto_init: size fault\n");		return -EINVAL;	}	/* Register the socket-side information for inet6_create.  */	for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)		INIT_LIST_HEAD(r);	/* We MUST register RAW sockets before we create the ICMP6,	 * IGMP6, or NDISC control sockets.	 */	inet6_register_protosw(&rawv6_protosw);	/*	 *	ipngwg API draft makes clear that the correct semantics	 *	for TCP and UDP is to consider one TCP and UDP instance	 *	in a host availiable by both INET and INET6 APIs and	 *	able to communicate via both network protocols.	 */#if defined(MODULE) && defined(CONFIG_SYSCTL)	ipv6_sysctl_register();#endif	err = icmpv6_init(&inet6_family_ops);	if (err)		goto icmp_fail;	err = ndisc_init(&inet6_family_ops);	if (err)		goto ndisc_fail;	err = igmp6_init(&inet6_family_ops);	if (err)		goto igmp_fail;	/* Create /proc/foo6 entries. */#ifdef CONFIG_PROC_FS	err = -ENOMEM;	if (!proc_net_create("raw6", 0, raw6_get_info))		goto proc_raw6_fail;	if (!proc_net_create("tcp6", 0, tcp6_get_info))		goto proc_tcp6_fail;	if (!proc_net_create("udp6", 0, udp6_get_info))		goto proc_udp6_fail;	if (!proc_net_create("sockstat6", 0, afinet6_get_info))		goto proc_sockstat6_fail;	if (!proc_net_create("snmp6", 0, afinet6_get_snmp))		goto proc_snmp6_fail;#endif	ipv6_netdev_notif_init();	ipv6_packet_init();	ip6_route_init();	ip6_flowlabel_init();	addrconf_init();	sit_init();	/* Init v6 transport protocols. */	udpv6_init();	tcpv6_init();	/* Now the userspace is allowed to create INET6 sockets. */	(void) sock_register(&inet6_family_ops);		return 0;#ifdef CONFIG_PROC_FSproc_snmp6_fail:	proc_net_remove("sockstat6");proc_sockstat6_fail:	proc_net_remove("udp6");proc_udp6_fail:	proc_net_remove("tcp6");proc_tcp6_fail:        proc_net_remove("raw6");proc_raw6_fail:	igmp6_cleanup();#endifigmp_fail:	ndisc_cleanup();ndisc_fail:	icmpv6_cleanup();icmp_fail:#if defined(MODULE) && defined(CONFIG_SYSCTL)	ipv6_sysctl_unregister();#endif	return err;}module_init(inet6_init);#ifdef MODULEstatic void inet6_exit(void){	/* First of all disallow new sockets creation. */	sock_unregister(PF_INET6);#ifdef CONFIG_PROC_FS	proc_net_remove("raw6");	proc_net_remove("tcp6");	proc_net_remove("udp6");	proc_net_remove("sockstat6");	proc_net_remove("snmp6");#endif	/* Cleanup code parts. */	sit_cleanup();	ipv6_netdev_notif_cleanup();	ip6_flowlabel_cleanup();	addrconf_cleanup();	ip6_route_cleanup();	ipv6_packet_cleanup();	igmp6_cleanup();	ndisc_cleanup();	icmpv6_cleanup();#ifdef CONFIG_SYSCTL	ipv6_sysctl_unregister();	#endif}module_exit(inet6_exit);#endif /* MODULE */MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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