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

📄 ip_ioctl.c

📁 操作系统源代码
💻 C
字号:
/*ip_ioctl.c*/#include "inet.h"#include "buf.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"INIT_PANIC();FORWARD 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 ));PUBLIC int ip_ioctl (fd, req)int fd;int req;{	ip_fd_t *ip_fd;	int type;assert (fd>=0 && fd<=IP_FD_NR);	ip_fd= &ip_fd_table[fd];	type= req & IOCTYPE_MASK;	assert (ip_fd->if_flags & IFF_INUSE);	switch (type)	{	case NWIOSIPOPT & IOCTYPE_MASK:		{			nwio_ipopt_t *ipopt;			nwio_ipopt_t oldopt, newopt;			acc_t *data;			int result;			unsigned int new_en_flags, new_di_flags,				old_en_flags, old_di_flags;			unsigned long new_flags;			if (req != NWIOSIPOPT)				break;			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)			{				reply_thr_get (ip_fd, EBADMODE, TRUE);				return NW_OK;			}			/* NWIO_ACC_MASK */			if (new_di_flags & NWIO_ACC_MASK)			{				reply_thr_get (ip_fd, EBADMODE, TRUE);				return NW_OK;				/* you can't disable access modes */			}			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)))			{				reply_thr_get(ip_fd, EBADMODE, TRUE);				return NW_OK;			}			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 & IOCTYPE_MASK:		{			nwio_ipopt_t *ipopt;			acc_t *acc;			int result;			if (req != NWIOGIPOPT)				break;			acc= bf_memreq(sizeof(nwio_ipopt_t));			ipopt= (nwio_ipopt_t *)ptr2acc_data(acc);			*ipopt= ip_fd->if_ipopt;			result= (*ip_fd->if_put_userdata)(ip_fd->				if_srfd, 0, acc, TRUE);			return (*ip_fd->if_put_userdata)(ip_fd->				if_srfd, result, (acc_t *)0, TRUE);		}	case NWIOSIPCONF & IOCTYPE_MASK:		{			nwio_ipconf_t *ipconf;			ip_port_t *ip_port;			acc_t *data;			int old_ip_flags;			ip_port= ip_fd->if_port;			if (req != NWIOSIPCONF)				break;			data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,				0, sizeof(nwio_ipconf_t), TRUE);			data= bf_packIffLess (data,				sizeof(nwio_ipconf_t));			assert (data->acc_length == sizeof(nwio_ipconf_t));			old_ip_flags= ip_port->ip_flags;			ipconf= (nwio_ipconf_t *)ptr2acc_data(data);			if (ipconf->nwic_flags & ~NWIC_FLAGS)				return (*ip_fd->if_put_userdata)(ip_fd->					if_srfd, EBADMODE, (acc_t *)0, TRUE);			if (ipconf->nwic_flags & NWIC_IPADDR_SET)			{				ip_port->ip_ipaddr= ipconf->nwic_ipaddr;				ip_port->ip_flags |= IPF_IPADDRSET;				switch (ip_port->ip_dl_type)				{				case IPDL_ETH:					set_ipaddr (ip_port->ip_dl.						dl_eth.de_port,						ip_port->ip_ipaddr);					break;				default:					ip_panic(( "unknown dl_type" ));				}			}			if (ipconf->nwic_flags & NWIC_NETMASK_SET)			{				ip_port->ip_netmask=					ipconf->nwic_netmask;				ip_port->ip_flags |= IPF_NETMASKSET;			}			if (!(old_ip_flags & IPF_IPADDRSET) && 				(ip_port->ip_flags & IPF_IPADDRSET) &&				!(ip_port->ip_flags & IPF_NETMASKSET))			{				icmp_getnetmask(ip_port-ip_port_table);			}			bf_afree(data);			return (*ip_fd->if_put_userdata)(ip_fd->				if_srfd, NW_OK, (acc_t *)0, TRUE);		}	case NWIOGIPCONF & IOCTYPE_MASK:		{			nwio_ipconf_t *ipconf;			ip_port_t *ip_port;			acc_t *data;			int result;			ip_port= ip_fd->if_port;			if (req != NWIOGIPCONF)				break;			if (!(ip_port->ip_flags & IPF_IPADDRSET))			{				ip_fd->if_flags |= IFF_GIPCONF_IP;#if DEBUG & 256 { where(); printf("(ip_fd_t *)0x%x->if_flags= 0x%x\n", ip_fd, ip_fd->if_flags); }#endif				return NW_SUSPEND;			}			ip_fd->if_flags &= ~IFF_GIPCONF_IP;			data= bf_memreq(sizeof(nwio_ipconf_t));			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_netmask;			if (ip_port->ip_flags & IPF_NETMASKSET)				ipconf->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 NWIOIPGROUTE & IOCTYPE_MASK:		{			acc_t *data;			nwio_route_t *route_ent;			int result;			if (req != NWIOIPGROUTE)				break;			data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,				0, sizeof(nwio_route_t), TRUE);			data= bf_packIffLess (data, sizeof(nwio_route_t) );			route_ent= (nwio_route_t *)ptr2acc_data(data);			result= ipr_get_route(route_ent->nwr_ent_no, route_ent);			if (result>=0)				(*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 NWIOIPSROUTE & IOCTYPE_MASK:		{			acc_t *data;			nwio_route_t *route_ent;			route_t *route;			int result;			if (req != NWIOIPSROUTE)				break;			data= (*ip_fd->if_get_userdata)(ip_fd->if_srfd,				0, sizeof(nwio_route_t), TRUE);			data= bf_packIffLess (data, sizeof(nwio_route_t) );			route_ent= (nwio_route_t *)ptr2acc_data(data);			route= ipr_add_route(route_ent->nwr_dest,				route_ent->nwr_netmask, route_ent->nwr_gateway,				ip_fd->if_port-ip_port_table, (time_t)0, 				route_ent->nwr_dist, !!(route_ent->nwr_flags &					NWRF_FIXED), route_ent->nwr_pref);			bf_afree(data);			if (route)				result= NW_OK;			else			{#if DEBUG { where(); printf("out of routing table entries\n"); }#endif				result= ENOMEM;			}			return (*ip_fd->if_put_userdata)(ip_fd->if_srfd,				result, (acc_t *)0, TRUE);		}	default:		break;	}#if DEBUG { where(); printf("replying EBADIOCTL\n"); }#endif	return (*ip_fd->if_put_userdata)(ip_fd-> if_srfd, EBADIOCTL,		(acc_t *)0, TRUE);}PRIVATE int ip_checkopt (ip_fd)ip_fd_t *ip_fd;{/* bug: we don't check access modes yet */	unsigned long flags;	unsigned int en_di_flags;	ip_port_t *port;	int result;	flags= ip_fd->if_ipopt.nwio_flags;	en_di_flags= (flags >>16) | (flags & 0xffff);	if (flags & NWIO_HDR_O_SPEC)	{		result= ip_chk_hdropt (ip_fd->if_ipopt.nwio_hdropt.iho_data,			ip_fd->if_ipopt.nwio_hdropt.iho_opt_siz);		if (result<0)			return result;	}	if ((en_di_flags & NWIO_ACC_MASK) &&		(en_di_flags & NWIO_LOC_MASK) &&		(en_di_flags & NWIO_BROAD_MASK) &&		(en_di_flags & NWIO_REM_MASK) &&		(en_di_flags & NWIO_PROTO_MASK) &&		(en_di_flags & NWIO_HDR_O_MASK) &&		(en_di_flags & NWIO_RW_MASK))	{		ip_fd->if_flags |= IFF_OPTSET;		if (ip_fd->if_rd_buf)			if (get_time() > ip_fd->if_exp_tim ||				!ip_ok_for_fd(ip_fd, ip_fd->if_rd_buf))			{				bf_afree(ip_fd->if_rd_buf);				ip_fd->if_rd_buf= 0;			}	}	else	{		ip_fd->if_flags &= ~IFF_OPTSET;		if (ip_fd->if_rd_buf)		{			bf_afree(ip_fd->if_rd_buf);			ip_fd->if_rd_buf= 0;		}	}	return NW_OK;}PRIVATE void reply_thr_get(ip_fd, reply, for_ioctl)ip_fd_t *ip_fd;size_t reply;int for_ioctl;{	acc_t *result;	result= (ip_fd->if_get_userdata)(ip_fd->if_srfd, reply,		(size_t)0, for_ioctl);	assert (!result);}

⌨️ 快捷键说明

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