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

📄 ip_ioctl.c

📁 minix3的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*ip_ioctl.cCopyright 1995 Philip Homburg*/#include "inet.h"#include "buf.h"#include "event.h"#include "type.h"#include "arp.h"#include "assert.h"#include "clock.h"#include "icmp_lib.h"#include "ip.h"#include "ip_int.h"#include "ipr.h"THIS_FILEFORWARD int ip_checkopt ARGS(( ip_fd_t *ip_fd ));FORWARD void reply_thr_get ARGS(( ip_fd_t *ip_fd, size_t	reply, int for_ioctl ));FORWARD void report_addr ARGS(( ip_port_t *ip_port ));PUBLIC int ip_ioctl (fd, req)int fd;ioreq_t req;{	ip_fd_t *ip_fd;	ip_port_t *ip_port;	nwio_ipopt_t *ipopt;	nwio_ipopt_t oldopt, newopt;	nwio_ipconf2_t *ipconf2;	nwio_ipconf_t *ipconf;	nwio_route_t *route_ent;	acc_t *data;	int result;	unsigned int new_en_flags, new_di_flags,		old_en_flags, old_di_flags;	unsigned long new_flags;	int ent_no, r;	nwio_ipconf_t ipconf_var;	assert (fd>=0 && fd<=IP_FD_NR);	ip_fd= &ip_fd_table[fd];	assert (ip_fd->if_flags & IFF_INUSE);	switch (req)	{	case NWIOSIPOPT:		ip_port= ip_fd->if_port;		if (!(ip_port->ip_flags & IPF_IPADDRSET))		{			ip_fd->if_ioctl= NWIOSIPOPT;			ip_fd->if_flags |= IFF_IOCTL_IP;			return NW_SUSPEND;		}		ip_fd->if_flags &= ~IFF_IOCTL_IP;		data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0,			sizeof(nwio_ipopt_t), TRUE);		data= bf_packIffLess (data, sizeof(nwio_ipopt_t));		assert (data->acc_length == sizeof(nwio_ipopt_t));		ipopt= (nwio_ipopt_t *)ptr2acc_data(data);		oldopt= ip_fd->if_ipopt;		newopt= *ipopt;		old_en_flags= oldopt.nwio_flags & 0xffff;		old_di_flags= (oldopt.nwio_flags >> 16) & 0xffff;		new_en_flags= newopt.nwio_flags & 0xffff;		new_di_flags= (newopt.nwio_flags >> 16) & 0xffff;		if (new_en_flags & new_di_flags)		{			bf_afree(data);			reply_thr_get (ip_fd, EBADMODE, TRUE);			return NW_OK;		}		/* NWIO_ACC_MASK */		if (new_di_flags & NWIO_ACC_MASK)		{			bf_afree(data);			reply_thr_get (ip_fd, EBADMODE, TRUE);			return NW_OK;			/* access modes can't be disable */		}		if (!(new_en_flags & NWIO_ACC_MASK))			new_en_flags |= (old_en_flags & NWIO_ACC_MASK);		/* NWIO_LOC_MASK */		if (!((new_en_flags|new_di_flags) & NWIO_LOC_MASK))		{			new_en_flags |= (old_en_flags & NWIO_LOC_MASK);			new_di_flags |= (old_di_flags & NWIO_LOC_MASK);		}		/* NWIO_BROAD_MASK */		if (!((new_en_flags|new_di_flags) & NWIO_BROAD_MASK))		{			new_en_flags |= (old_en_flags & NWIO_BROAD_MASK);			new_di_flags |= (old_di_flags & NWIO_BROAD_MASK);		}		/* NWIO_REM_MASK */		if (!((new_en_flags|new_di_flags) & NWIO_REM_MASK))		{			new_en_flags |= (old_en_flags & NWIO_REM_MASK);			new_di_flags |= (old_di_flags & NWIO_REM_MASK);			newopt.nwio_rem= oldopt.nwio_rem;		}		/* NWIO_PROTO_MASK */		if (!((new_en_flags|new_di_flags) & NWIO_PROTO_MASK))		{			new_en_flags |= (old_en_flags & NWIO_PROTO_MASK);			new_di_flags |= (old_di_flags & NWIO_PROTO_MASK);			newopt.nwio_proto= oldopt.nwio_proto;		}		/* NWIO_HDR_O_MASK */		if (!((new_en_flags|new_di_flags) & NWIO_HDR_O_MASK))		{			new_en_flags |= (old_en_flags & NWIO_HDR_O_MASK);			new_di_flags |= (old_di_flags & NWIO_HDR_O_MASK);			newopt.nwio_tos= oldopt.nwio_tos;			newopt.nwio_ttl= oldopt.nwio_ttl;			newopt.nwio_df= oldopt.nwio_df;			newopt.nwio_hdropt= oldopt.nwio_hdropt;		}		/* NWIO_RW_MASK */		if (!((new_en_flags|new_di_flags) & NWIO_RW_MASK))		{			new_en_flags |= (old_en_flags & NWIO_RW_MASK);			new_di_flags |= (old_di_flags & NWIO_RW_MASK);		}		new_flags= ((unsigned long)new_di_flags << 16) | new_en_flags;		if ((new_flags & NWIO_RWDATONLY) && (new_flags &			(NWIO_REMANY|NWIO_PROTOANY|NWIO_HDR_O_ANY)))		{			bf_afree(data);			reply_thr_get(ip_fd, EBADMODE, TRUE);			return NW_OK;		}		if (ip_fd->if_flags & IFF_OPTSET)			ip_unhash_proto(ip_fd);		newopt.nwio_flags= new_flags;		ip_fd->if_ipopt= newopt;		result= ip_checkopt(ip_fd);		if (result<0)			ip_fd->if_ipopt= oldopt;		bf_afree(data);		reply_thr_get (ip_fd, result, TRUE);		return NW_OK;	case NWIOGIPOPT:		data= bf_memreq(sizeof(nwio_ipopt_t));		ipopt= (nwio_ipopt_t *)ptr2acc_data(data);		*ipopt= ip_fd->if_ipopt;		result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, 									TRUE);		return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, 							(acc_t *)0, TRUE);	case NWIOSIPCONF2:	case NWIOSIPCONF:		ip_port= ip_fd->if_port;		if (req == NWIOSIPCONF2)		{			data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, 				sizeof(*ipconf2), TRUE);			data= bf_packIffLess (data, sizeof(*ipconf2));			assert (data->acc_length == sizeof(*ipconf2));			ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data);			ipconf= &ipconf_var;			ipconf->nwic_flags= ipconf2->nwic_flags;			ipconf->nwic_ipaddr= ipconf2->nwic_ipaddr;			ipconf->nwic_netmask= ipconf2->nwic_netmask;			ipconf->nwic_flags &= ~NWIC_MTU_SET;		}		else		{			data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd, 0, 				sizeof(*ipconf), TRUE);			data= bf_packIffLess (data, sizeof(*ipconf));			assert (data->acc_length == sizeof(*ipconf));			ipconf= (nwio_ipconf_t *)ptr2acc_data(data);		}		r= ip_setconf(ip_port-ip_port_table, ipconf);		bf_afree(data);		return (*ip_fd->if_put_userdata)(ip_fd-> if_srfd, r, 							(acc_t *)0, TRUE);	case NWIOGIPCONF2:		ip_port= ip_fd->if_port;		if (!(ip_port->ip_flags & IPF_IPADDRSET))		{			ip_fd->if_ioctl= NWIOGIPCONF2;			ip_fd->if_flags |= IFF_IOCTL_IP;			return NW_SUSPEND;		}		ip_fd->if_flags &= ~IFF_IOCTL_IP;		data= bf_memreq(sizeof(nwio_ipconf_t));		ipconf2= (nwio_ipconf2_t *)ptr2acc_data(data);		ipconf2->nwic_flags= NWIC_IPADDR_SET;		ipconf2->nwic_ipaddr= ip_port->ip_ipaddr;		ipconf2->nwic_netmask= ip_port->ip_subnetmask;		if (ip_port->ip_flags & IPF_NETMASKSET)			ipconf2->nwic_flags |= NWIC_NETMASK_SET;		result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, 									TRUE);		return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, 							(acc_t *)0, TRUE);		case NWIOGIPCONF:		ip_port= ip_fd->if_port;		if (!(ip_port->ip_flags & IPF_IPADDRSET))		{			ip_fd->if_ioctl= NWIOGIPCONF;			ip_fd->if_flags |= IFF_IOCTL_IP;			return NW_SUSPEND;		}		ip_fd->if_flags &= ~IFF_IOCTL_IP;		data= bf_memreq(sizeof(*ipconf));		ipconf= (nwio_ipconf_t *)ptr2acc_data(data);		ipconf->nwic_flags= NWIC_IPADDR_SET;		ipconf->nwic_ipaddr= ip_port->ip_ipaddr;		ipconf->nwic_netmask= ip_port->ip_subnetmask;		if (ip_port->ip_flags & IPF_NETMASKSET)			ipconf->nwic_flags |= NWIC_NETMASK_SET;		ipconf->nwic_mtu= ip_port->ip_mtu;		result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0, data, 									TRUE);		return (*ip_fd->if_put_userdata)(ip_fd->if_srfd, result, 							(acc_t *)0, TRUE);	case NWIOGIPOROUTE:		data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,			0, sizeof(nwio_route_t), TRUE);		if (data == NULL)		{			return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,				EFAULT, NULL, TRUE);		}		data= bf_packIffLess (data, sizeof(nwio_route_t) );		route_ent= (nwio_route_t *)ptr2acc_data(data);		ent_no= route_ent->nwr_ent_no;		bf_afree(data);		data= bf_memreq(sizeof(nwio_route_t));		route_ent= (nwio_route_t *)ptr2acc_data(data);		result= ipr_get_oroute(ent_no, route_ent);		if (result < 0)			bf_afree(data);		else		{			assert(result == NW_OK);			result= (*ip_fd->if_put_userdata)(ip_fd->if_srfd, 0,				data, TRUE);		}		return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,			result, (acc_t *)0, TRUE);	case NWIOSIPOROUTE:		data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,			0, sizeof(nwio_route_t), TRUE);		if (data == NULL)		{			return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,				EFAULT, NULL, TRUE);		}		if (!(ip_fd->if_port->ip_flags & IPF_IPADDRSET))		{			/* Interface is down, no changes allowed */			return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,				EINVAL, NULL, TRUE);		}		data= bf_packIffLess (data, sizeof(nwio_route_t) );		route_ent= (nwio_route_t *)ptr2acc_data(data);		result= ipr_add_oroute(ip_fd->if_port-ip_port_table, 			route_ent->nwr_dest, route_ent->nwr_netmask, 			route_ent->nwr_gateway, (time_t)0, 			route_ent->nwr_dist, route_ent->nwr_mtu,			!!(route_ent->nwr_flags & NWRF_STATIC), 			route_ent->nwr_pref, NULL);		bf_afree(data);		return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,			result, (acc_t *)0, TRUE);	case NWIODIPOROUTE:		data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,			0, sizeof(nwio_route_t), TRUE);		if (data == NULL)		{			return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,				EFAULT, NULL, TRUE);		}		data= bf_packIffLess (data, sizeof(nwio_route_t) );		route_ent= (nwio_route_t *)ptr2acc_data(data);		result= ipr_del_oroute(ip_fd->if_port-ip_port_table, 			route_ent->nwr_dest, route_ent->nwr_netmask, 			route_ent->nwr_gateway,			!!(route_ent->nwr_flags & NWRF_STATIC));		bf_afree(data);		return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,			result, (acc_t *)0, TRUE);

⌨️ 快捷键说明

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