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

📄 af_ipx.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
	sg = (struct sockaddr_ipx *)&rt.rt_gateway;	st = (struct sockaddr_ipx *)&rt.rt_dst;	if(!(rt.rt_flags & RTF_GATEWAY))		return (-EINVAL);	/* Direct routes are fixed */	if(sg->sipx_family != AF_IPX)		return (-EINVAL);	if(st->sipx_family != AF_IPX)		return (-EINVAL);	switch(cmd)	{		case SIOCDELRT:			return (ipxrtr_delete(st->sipx_network));		case SIOCADDRT:		{			struct ipx_route_definition f;			f.ipx_network=st->sipx_network;			f.ipx_router_network=sg->sipx_network;			memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);			return (ipxrtr_create(&f));		}		default:			return (-EINVAL);	}}static const char *ipx_frame_name(unsigned short frame){	switch(ntohs(frame)) 	{		case ETH_P_IPX:			return ("EtherII");		case ETH_P_802_2:			return ("802.2");		case ETH_P_SNAP:			return ("SNAP");		case ETH_P_802_3:			return ("802.3");		case ETH_P_TR_802_2:			return ("802.2TR");		default:			return ("None");	}}static const char *ipx_device_name(ipx_interface *intrfc){	return (intrfc->if_internal ? "Internal" :		(intrfc->if_dev ? intrfc->if_dev->name : "Unknown"));}/* Called from proc fs */static int ipx_interface_get_info(char *buffer, char **start, off_t offset,				  int length){	ipx_interface *i;	off_t begin = 0, pos = 0;	int len = 0;	/* Theory.. Keep printing in the same place until we pass offset */	len += sprintf(buffer,"%-11s%-15s%-9s%-11s%s", "Network",		"Node_Address", "Primary", "Device", "Frame_Type");#ifdef IPX_REFCNT_DEBUG	len += sprintf(buffer + len, "  refcnt");#endif	strcat(buffer+len++, "\n");	spin_lock_bh(&ipx_interfaces_lock);	for(i = ipx_interfaces; i != NULL; i = i->if_next)	{		len += sprintf(buffer+len, "%08lX   ", (long unsigned int)ntohl(i->if_netnum));		len += sprintf(buffer+len,"%02X%02X%02X%02X%02X%02X   ",				i->if_node[0], i->if_node[1], i->if_node[2],				i->if_node[3], i->if_node[4], i->if_node[5]);		len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ?			"Yes" : "No");		len += sprintf(buffer+len, "%-11s", ipx_device_name(i));		len += sprintf(buffer+len, "%-9s",			ipx_frame_name(i->if_dlink_type));#ifdef IPX_REFCNT_DEBUG		len += sprintf(buffer+len,"%6d",atomic_read(&i->refcnt));#endif		strcat(buffer+len++, "\n");		/* Are we still dumping unwanted data then discard the record */		pos = begin + len;		if(pos < offset)		{			len   = 0;	/* Keep dumping into the buffer start */			begin = pos;		}		if(pos > offset + length)	/* We have dumped enough */			break;	}	spin_unlock_bh(&ipx_interfaces_lock);	/* The data in question runs from begin to begin+len */	*start = buffer + (offset - begin);	/* Start of wanted data */	len -= (offset - begin); /* Remove unwanted header data from length */	if(len > length)		len = length;	/* Remove unwanted tail data from length */	return (len);}static int ipx_get_info(char *buffer, char **start, off_t offset, int length){	struct sock *s;	ipx_interface *i;	off_t begin = 0, pos = 0;	int len = 0;	/* Theory.. Keep printing in the same place until we pass offset */#ifdef CONFIG_IPX_INTERN	len += sprintf(buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address",#else	len += sprintf(buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address",#endif	/* CONFIG_IPX_INTERN */			"Remote_Address", "Tx_Queue", "Rx_Queue",			"State", "Uid");	spin_lock_bh(&ipx_interfaces_lock);	for(i = ipx_interfaces; i != NULL; i = i->if_next)	{		ipxitf_hold(i);		spin_lock_bh(&i->if_sklist_lock);		for(s = i->if_sklist; s != NULL; s = s->next)		{#ifdef CONFIG_IPX_INTERN			len += sprintf(buffer+len,				       "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",                                       (unsigned long) htonl(s->protinfo.af_ipx.intrfc->if_netnum),				       s->protinfo.af_ipx.node[0],				       s->protinfo.af_ipx.node[1],				       s->protinfo.af_ipx.node[2],				       s->protinfo.af_ipx.node[3],				       s->protinfo.af_ipx.node[4],				       s->protinfo.af_ipx.node[5],				       htons(s->protinfo.af_ipx.port));#else			len += sprintf(buffer+len,"%08lX:%04X  ",				       (unsigned long)htonl(i->if_netnum),				       htons(s->protinfo.af_ipx.port));#endif	/* CONFIG_IPX_INTERN */			if(s->state != TCP_ESTABLISHED)				len += sprintf(buffer+len, "%-28s", "Not_Connected");			else			{				len += sprintf(buffer+len,					"%08lX:%02X%02X%02X%02X%02X%02X:%04X  ",					(unsigned long) htonl(s->protinfo.af_ipx.dest_addr.net),					s->protinfo.af_ipx.dest_addr.node[0],					s->protinfo.af_ipx.dest_addr.node[1],					s->protinfo.af_ipx.dest_addr.node[2],					s->protinfo.af_ipx.dest_addr.node[3],					s->protinfo.af_ipx.dest_addr.node[4],					s->protinfo.af_ipx.dest_addr.node[5],					htons(s->protinfo.af_ipx.dest_addr.sock));			}			len += sprintf(buffer+len,"%08X  %08X  ",				atomic_read(&s->wmem_alloc),				atomic_read(&s->rmem_alloc));			len += sprintf(buffer+len,"%02X     %03d\n",				s->state, SOCK_INODE(s->socket)->i_uid);			pos = begin + len;			if(pos < offset)			{				len   = 0;				begin = pos;			}			if(pos > offset + length)  /* We have dumped enough */				break;		}		spin_unlock_bh(&i->if_sklist_lock);		ipxitf_put(i);	}	spin_unlock_bh(&ipx_interfaces_lock);	/* The data in question runs from begin to begin+len */	*start = buffer + (offset-begin);	len -= (offset - begin);	if(len > length)		len = length;	return (len);}static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length){	ipx_route *rt;	off_t begin = 0, pos = 0;	int len = 0;	len += sprintf(buffer,"%-11s%-13s%s\n",			"Network", "Router_Net", "Router_Node");	read_lock_bh(&ipx_routes_lock);	for(rt = ipx_routes; rt != NULL; rt = rt->ir_next)	{		len += sprintf(buffer+len,"%08lX   ", (long unsigned int) ntohl(rt->ir_net));		if(rt->ir_routed)		{			len += sprintf(buffer+len,"%08lX     %02X%02X%02X%02X%02X%02X\n",				(long unsigned int) ntohl(rt->ir_intrfc->if_netnum),				rt->ir_router_node[0], rt->ir_router_node[1],				rt->ir_router_node[2], rt->ir_router_node[3],				rt->ir_router_node[4], rt->ir_router_node[5]);		}		else		{			len += sprintf(buffer+len, "%-13s%s\n",					"Directly", "Connected");		}		pos = begin + len;		if(pos < offset)		{			len   = 0;			begin = pos;		}		if(pos > offset + length)			break;	}	read_unlock_bh(&ipx_routes_lock);	*start = buffer + (offset - begin);	len -= (offset - begin);	if(len > length)		len = length;	return (len);}/**************************************************************************\*                                                                          ** Handling for system calls applied via the various interfaces to an       ** IPX socket object.                                                       **                                                                          *\**************************************************************************/static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen){	struct sock *sk;	int err, opt;	sk = sock->sk;	if(optlen != sizeof(int))		return (-EINVAL);	err = get_user(opt, (unsigned int *)optval);	if(err)		return (err);	switch(level)	{		case SOL_IPX:			switch(optname)			{				case IPX_TYPE:					sk->protinfo.af_ipx.type = opt;					return (0);				default:					return (-ENOPROTOOPT);			}			break;		default:			return (-ENOPROTOOPT);	}}static int ipx_getsockopt(struct socket *sock, int level, int optname,	char *optval, int *optlen){	struct sock *sk;	int val=0;	int len;	sk = sock->sk;	switch(level)	{		case SOL_IPX:			switch(optname)			{				case IPX_TYPE:					val = sk->protinfo.af_ipx.type;					break;				default:					return (-ENOPROTOOPT);			}			break;		default:			return (-ENOPROTOOPT);	}	if(get_user(len, optlen))		return (-EFAULT);	len = min(len, sizeof(int));	if(put_user(len, optlen))		return (-EFAULT);	if(copy_to_user(optval, &val, len))		return (-EFAULT);	return (0);}static int ipx_create(struct socket *sock, int protocol){	struct sock *sk;	switch(sock->type)	{		case SOCK_DGRAM:			sk = sk_alloc(PF_IPX, GFP_KERNEL, 1);			if(sk == NULL)                		return (-ENOMEM);                        sock->ops = &ipx_dgram_ops;                        break;		case SOCK_SEQPACKET:			/*			 * From this point on SPX sockets are handled			 * by af_spx.c and the methods replaced.			 */			if(spx_family_ops)				return (spx_family_ops->create(sock,protocol));			/* Fall through if SPX is not loaded */		case SOCK_STREAM:       /* Allow higher levels to piggyback */		default:			return (-ESOCKTNOSUPPORT);	}#ifdef IPX_REFCNT_DEBUG        atomic_inc(&ipx_sock_nr);        printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk,			atomic_read(&ipx_sock_nr));#endif	sock_init_data(sock, sk);	sk->destruct	= NULL;	sk->no_check 	= 1;		/* Checksum off by default */	MOD_INC_USE_COUNT;	return (0);}static int ipx_release(struct socket *sock){	struct sock *sk = sock->sk;	if(sk == NULL)		return (0);	if(!sk->dead)		sk->state_change(sk);	sk->dead = 1;	sock->sk = NULL;	ipx_destroy_socket(sk);	if(sock->type == SOCK_DGRAM)		MOD_DEC_USE_COUNT;	return (0);}/* caller must hold a referente to intrfc */static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc){	unsigned short socketNum = intrfc->if_sknum;	spin_lock_bh(&intrfc->if_sklist_lock);	if(socketNum < IPX_MIN_EPHEMERAL_SOCKET)		socketNum = IPX_MIN_EPHEMERAL_SOCKET;	while(__ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)	{		if(socketNum > IPX_MAX_EPHEMERAL_SOCKET)			socketNum = IPX_MIN_EPHEMERAL_SOCKET;		else			socketNum++;	}	spin_unlock_bh(&intrfc->if_sklist_lock);	intrfc->if_sknum = socketNum;	return (ntohs(socketNum));}static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len){	struct sock *sk;	ipx_interface *intrfc;	struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr;	int ret;	sk = sock->sk;	if(sk->zapped == 0)		return (-EINVAL);	if(addr_len != sizeof(struct sockaddr_ipx))		return (-EINVAL);	intrfc = ipxitf_find_using_net(addr->sipx_network);	if(intrfc == NULL)		return (-EADDRNOTAVAIL);	if(addr->sipx_port == 0)	{		addr->sipx_port = ipx_first_free_socketnum(intrfc);		ret = -EINVAL;		if(addr->sipx_port == 0)			goto out;	}	/* protect IPX system stuff like routing/sap */	ret = -EACCES;	if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !capable(CAP_NET_ADMIN))		goto out;	sk->protinfo.af_ipx.port = addr->sipx_port;#ifdef CONFIG_IPX_INTERN	if(intrfc == ipx_internal_net)	{		/* The source address is to be set explicitly if the		 * socket is to be bound on the internal network. If a		 * node number 0 was specified, the default is used.		 */		ret = -EINVAL;		if(memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN) == 0)			goto out;		if(memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0)		{			memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,			       IPX_NODE_LEN);		}		else		{			memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN);		}		ret = -EADDRINUSE;		if(ipxitf_find_internal_socket(intrfc,			sk->protinfo.af_ipx.node,			sk->protinfo.af_ipx.port) != NULL)		{			SOCK_DEBUG(sk,				"IPX: bind failed because port %X in use.\n",				ntohs((int)addr->sipx_port));			goto out;		}	}	else	{		/* Source addresses are easy. It must be our		 * network:node pair for an interface routed to IPX		 * with the ipx routing ioctl()		 */		memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,			IPX_NODE_LEN);		ret = -EADDRINUSE;		if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL)		{			SOCK_DEBUG(sk,				"IPX: bind failed because port %X in use.\n",				ntohs((int)addr->sipx_port));			goto out;		}	}#else	/* !def CONFIG_IPX_INTERN */	/* Source addresses are easy. It must be our network:node pair for	   an interface routed to IPX with the ipx routing ioctl() */	ret = -EADDRINUSE;	if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL)	{		SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n",				ntohs((int)addr->sipx_port));		goto out;	}#endif	/* CONFIG_IPX_INTERN */	ipxitf_insert_socket(intrfc, sk);	sk->zapped = 0;	SOCK_DEBUG(sk, "IPX: bound socket 0x%04X.\n", ntohs(addr->sipx_port) );	ret = 0;out:	ipxitf_put(intrfc);	return ret;}static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,	int addr_len, int flags){	struct sock *sk = sock->sk;	struct sockaddr_ipx *addr;	sk->state	= TCP_CLOSE;	sock->state 	= SS_UNCONNECTED;	if(addr_len != sizeof(*addr))		return (-EINVAL);	addr = (struct sockaddr_ipx *)uaddr;	/* put the autobinding in */	if(sk->protinfo.af_ipx.port == 0)	{		struct sockaddr_ipx uaddr;		int ret;		uaddr.sipx_port		= 0;		uaddr.sipx_network 	= 0;

⌨️ 快捷键说明

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