Пример #1
0
static int
tap_dev_ioctl(int unit, u_long cmd, void *data, struct lwp *l)
{
	struct tap_softc *sc = device_lookup_private(&tap_cd, unit);

	if (sc == NULL)
		return ENXIO;

	switch (cmd) {
	case FIONREAD:
		{
			struct ifnet *ifp = &sc->sc_ec.ec_if;
			struct mbuf *m;
			int s;

			s = splnet();
			IFQ_POLL(&ifp->if_snd, m);

			if (m == NULL)
				*(int *)data = 0;
			else
				*(int *)data = m->m_pkthdr.len;
			splx(s);
			return 0;
		} 
	case TIOCSPGRP:
	case FIOSETOWN:
		return fsetown(&sc->sc_pgid, cmd, data);
	case TIOCGPGRP:
	case FIOGETOWN:
		return fgetown(sc->sc_pgid, cmd, data);
	case FIOASYNC:
		if (*(int *)data)
			sc->sc_flags |= TAP_ASYNCIO;
		else
			sc->sc_flags &= ~TAP_ASYNCIO;
		return 0;
	case FIONBIO:
		if (*(int *)data)
			sc->sc_flags |= TAP_NBIO;
		else
			sc->sc_flags &= ~TAP_NBIO;
		return 0;
#ifdef OTAPGIFNAME
	case OTAPGIFNAME:
#endif
	case TAPGIFNAME:
		{
			struct ifreq *ifr = (struct ifreq *)data;
			struct ifnet *ifp = &sc->sc_ec.ec_if;

			strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ);
			return 0;
		}
	default:
		return ENOTTY;
	}
}
Пример #2
0
/*ARGSUSED*/
static	int
logioctl(struct cdev *dev, u_long com, caddr_t data, int flag, struct thread *td)
{

	switch (com) {

	/* return number of characters immediately available */
	case FIONREAD:
		*(int *)data = msgbuf_getcount(msgbufp);
		break;

	case FIONBIO:
		break;

	case FIOASYNC:
		mtx_lock(&msgbuf_lock);
		if (*(int *)data)
			logsoftc.sc_state |= LOG_ASYNC;
		else
			logsoftc.sc_state &= ~LOG_ASYNC;
		mtx_unlock(&msgbuf_lock);
		break;

	case FIOSETOWN:
		return (fsetown(*(int *)data, &logsoftc.sc_sigio));

	case FIOGETOWN:
		*(int *)data = fgetown(&logsoftc.sc_sigio);
		break;

	/* This is deprecated, FIOSETOWN should be used instead. */
	case TIOCSPGRP:
		return (fsetown(-(*(int *)data), &logsoftc.sc_sigio));

	/* This is deprecated, FIOGETOWN should be used instead */
	case TIOCGPGRP:
		*(int *)data = -fgetown(&logsoftc.sc_sigio);
		break;

	default:
		return (ENOTTY);
	}
	return (0);
}
Пример #3
0
/*ARGSUSED*/
static	int
logioctl(struct dev_ioctl_args *ap)
{
	long l;

	switch (ap->a_cmd) {
	case FIONREAD:
		/* return number of characters immediately available */
		crit_enter();
		l = msgbufp->msg_bufx - msgbufp->msg_bufr;
		crit_exit();
		if (l < 0)
			l += msgbufp->msg_size;
		*(int *)ap->a_data = l;
		break;

	case FIOASYNC:
		if (*(int *)ap->a_data)
			logsoftc.sc_state |= LOG_ASYNC;
		else
			logsoftc.sc_state &= ~LOG_ASYNC;
		break;

	case FIOSETOWN:
		return (fsetown(*(int *)ap->a_data, &logsoftc.sc_sigio));

	case FIOGETOWN:
		*(int *)ap->a_data = fgetown(&logsoftc.sc_sigio);
		break;

	/* This is deprecated, FIOSETOWN should be used instead. */
	case TIOCSPGRP:
		return (fsetown(-(*(int *)ap->a_data), &logsoftc.sc_sigio));

	/* This is deprecated, FIOGETOWN should be used instead */
	case TIOCGPGRP:
		*(int *)ap->a_data = -fgetown(&logsoftc.sc_sigio);
		break;

	default:
		return (ENOTTY);
	}
	return (0);
}
Пример #4
0
int _getown(int argc, char ** argv) {
	if(argc > 1)
	{
		int res = fgetown(argv[1]);
		if(res >= 0) {
			printf("User #%d is %s's owner\n", res, argv[1]);
		} else {
			printf("Invalid file? Try that again man.\n");
		}
	}
	return 0;
}
Пример #5
0
static int
soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred,
    struct thread *td)
{
	struct socket *so = fp->f_data;
	int error = 0;

	switch (cmd) {
	case FIONBIO:
		SOCK_LOCK(so);
		if (*(int *)data)
			so->so_state |= SS_NBIO;
		else
			so->so_state &= ~SS_NBIO;
		SOCK_UNLOCK(so);
		break;

	case FIOASYNC:
		/*
		 * XXXRW: This code separately acquires SOCK_LOCK(so) and
		 * SOCKBUF_LOCK(&so->so_rcv) even though they are the same
		 * mutex to avoid introducing the assumption that they are
		 * the same.
		 */
		if (*(int *)data) {
			SOCK_LOCK(so);
			so->so_state |= SS_ASYNC;
			SOCK_UNLOCK(so);
			SOCKBUF_LOCK(&so->so_rcv);
			so->so_rcv.sb_flags |= SB_ASYNC;
			SOCKBUF_UNLOCK(&so->so_rcv);
			SOCKBUF_LOCK(&so->so_snd);
			so->so_snd.sb_flags |= SB_ASYNC;
			SOCKBUF_UNLOCK(&so->so_snd);
		} else {
			SOCK_LOCK(so);
			so->so_state &= ~SS_ASYNC;
			SOCK_UNLOCK(so);
			SOCKBUF_LOCK(&so->so_rcv);
			so->so_rcv.sb_flags &= ~SB_ASYNC;
			SOCKBUF_UNLOCK(&so->so_rcv);
			SOCKBUF_LOCK(&so->so_snd);
			so->so_snd.sb_flags &= ~SB_ASYNC;
			SOCKBUF_UNLOCK(&so->so_snd);
		}
		break;

	case FIONREAD:
		/* Unlocked read. */
		*(int *)data = sbavail(&so->so_rcv);
		break;

	case FIONWRITE:
		/* Unlocked read. */
		*(int *)data = sbavail(&so->so_snd);
		break;

	case FIONSPACE:
		/* Unlocked read. */
		if ((so->so_snd.sb_hiwat < sbused(&so->so_snd)) ||
		    (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt))
			*(int *)data = 0;
		else
			*(int *)data = sbspace(&so->so_snd);
		break;

	case FIOSETOWN:
		error = fsetown(*(int *)data, &so->so_sigio);
		break;

	case FIOGETOWN:
		*(int *)data = fgetown(&so->so_sigio);
		break;

	case SIOCSPGRP:
		error = fsetown(-(*(int *)data), &so->so_sigio);
		break;

	case SIOCGPGRP:
		*(int *)data = -fgetown(&so->so_sigio);
		break;

	case SIOCATMARK:
		/* Unlocked read. */
		*(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0;
		break;
	default:
		/*
		 * Interface/routing/protocol specific ioctls: interface and
		 * routing ioctls should have a different entry since a
		 * socket is unnecessary.
		 */
		if (IOCGROUP(cmd) == 'i')
			error = ifioctl(so, cmd, data, td);
		else if (IOCGROUP(cmd) == 'r') {
			CURVNET_SET(so->so_vnet);
			error = rtioctl_fib(cmd, data, so->so_fibnum);
			CURVNET_RESTORE();
		} else {
			CURVNET_SET(so->so_vnet);
			error = ((*so->so_proto->pr_usrreqs->pru_control)
			    (so, cmd, data, 0, td));
			CURVNET_RESTORE();
		}
		break;
	}
	return (error);
}
Пример #6
0
/*
 * MPSAFE
 */
int
soo_ioctl(struct file *fp, u_long cmd, caddr_t data,
	  struct ucred *cred, struct sysmsg *msg)
{
	struct socket *so;
	int error;

	so = (struct socket *)fp->f_data;

	switch (cmd) {
	case FIOASYNC:
		if (*(int *)data) {
			sosetstate(so, SS_ASYNC);
			atomic_set_int(&so->so_rcv.ssb_flags,  SSB_ASYNC);
			atomic_set_int(&so->so_snd.ssb_flags, SSB_ASYNC);
		} else {
			soclrstate(so, SS_ASYNC);
			atomic_clear_int(&so->so_rcv.ssb_flags, SSB_ASYNC);
			atomic_clear_int(&so->so_snd.ssb_flags, SSB_ASYNC);
		}
		error = 0;
		break;
	case FIONREAD:
		*(int *)data = so->so_rcv.ssb_cc;
		error = 0;
		break;
	case FIOSETOWN:
		error = fsetown(*(int *)data, &so->so_sigio);
		break;
	case FIOGETOWN:
		*(int *)data = fgetown(&so->so_sigio);
		error = 0;
		break;
	case SIOCSPGRP:
		error = fsetown(-(*(int *)data), &so->so_sigio);
		break;
	case SIOCGPGRP:
		*(int *)data = -fgetown(&so->so_sigio);
		error = 0;
		break;
	case SIOCATMARK:
		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
		error = 0;
		break;
	default:
		/*
		 * Interface/routing/protocol specific ioctls:
		 * interface and routing ioctls should have a
		 * different entry since a socket's unnecessary
		 */
		if (IOCGROUP(cmd) == 'i') {
			error = ifioctl(so, cmd, data, cred);
		} else if (IOCGROUP(cmd) == 'r') {
			error = rtioctl(cmd, data, cred);
		} else {
			error = so_pru_control_direct(so, cmd, data, NULL);
		}
		break;
	}
	return (error);
}
Пример #7
0
Файл: bpf.c Проект: SbIm/xnu-env
/* ARGSUSED */
int
bpfioctl(dev_t dev, u_long cmd, caddr_t addr, __unused int flags,
    struct proc *p)
{
	struct bpf_d *d;
	int error = 0;

	lck_mtx_lock(bpf_mlock);

	d = bpf_dtab[minor(dev)];
	if (d == 0 || d == (void *)1) {
		lck_mtx_unlock(bpf_mlock);
		return (ENXIO);
	}

	switch (cmd) {

	default:
		error = EINVAL;
		break;

	/*
	 * Check for read packet available.
	 */
	case FIONREAD:
		{
			int n;

			n = d->bd_slen;
			if (d->bd_hbuf)
				n += d->bd_hlen;

			*(int *)addr = n;
			break;
		}

	case SIOCGIFADDR:
		{
			struct ifnet *ifp;

			if (d->bd_bif == 0)
				error = EINVAL;
			else {
				ifp = d->bd_bif->bif_ifp;
				error = ifnet_ioctl(ifp, 0, cmd, addr);
			}
			break;
		}

	/*
	 * Get buffer len [for read()].
	 */
	case BIOCGBLEN:
		*(u_int *)addr = d->bd_bufsize;
		break;

	/*
	 * Set buffer length.
	 */
	case BIOCSBLEN:
#if BSD < 199103
		error = EINVAL;
#else
		if (d->bd_bif != 0)
			error = EINVAL;
		else {
			u_int size = *(u_int *)addr;

			if (size > bpf_maxbufsize)
				*(u_int *)addr = size = bpf_maxbufsize;
			else if (size < BPF_MINBUFSIZE)
				*(u_int *)addr = size = BPF_MINBUFSIZE;
			d->bd_bufsize = size;
		}
#endif
		break;

	/*
	 * Set link layer read filter.
	 */
	case BIOCSETF32: {
		struct bpf_program32 *prg32 = (struct bpf_program32 *)addr;
		error = bpf_setf(d, prg32->bf_len,
		    CAST_USER_ADDR_T(prg32->bf_insns));
		break;
	}

	case BIOCSETF64: {
		struct bpf_program64 *prg64 = (struct bpf_program64 *)addr;
		error = bpf_setf(d, prg64->bf_len, prg64->bf_insns);
		break;
	}

	/*
	 * Flush read packet buffer.
	 */
	case BIOCFLUSH:
		reset_d(d);
		break;

	/*
	 * Put interface into promiscuous mode.
	 */
	case BIOCPROMISC:
		if (d->bd_bif == 0) {
			/*
			 * No interface attached yet.
			 */
			error = EINVAL;
			break;
		}
		if (d->bd_promisc == 0) {
			lck_mtx_unlock(bpf_mlock);
			error = ifnet_set_promiscuous(d->bd_bif->bif_ifp, 1);
			lck_mtx_lock(bpf_mlock);
			if (error == 0)
				d->bd_promisc = 1;
		}
		break;

	/*
	 * Get device parameters.
	 */
	case BIOCGDLT:
		if (d->bd_bif == 0)
			error = EINVAL;
		else
			*(u_int *)addr = d->bd_bif->bif_dlt;
		break;

	/*
	 * Get a list of supported data link types.
	 */
	case BIOCGDLTLIST:
		if (d->bd_bif == NULL) {
			error = EINVAL;
		} else {
			error = bpf_getdltlist(d,
			    (struct bpf_dltlist *)addr, p);
		}
		break;

	/*
	 * Set data link type.
	 */
	case BIOCSDLT:
			if (d->bd_bif == NULL)
					error = EINVAL;
			else
					error = bpf_setdlt(d, *(u_int *)addr);
			break;

	/*
	 * Get interface name.
	 */
	case BIOCGETIF:
		if (d->bd_bif == 0)
			error = EINVAL;
		else {
			struct ifnet *const ifp = d->bd_bif->bif_ifp;
			struct ifreq *const ifr = (struct ifreq *)addr;

			snprintf(ifr->ifr_name, sizeof(ifr->ifr_name),
			    "%s%d", ifp->if_name, ifp->if_unit);
		}
		break;

	/*
	 * Set interface.
	 */
	case BIOCSETIF: {
		ifnet_t	ifp;
		ifp = ifunit(((struct ifreq *)addr)->ifr_name);
		if (ifp == NULL)
			error = ENXIO;
		else
			error = bpf_setif(d, ifp, 0);
		break;
	}

	/*
	 * Set read timeout.
	 */
	case BIOCSRTIMEOUT:
		{
			struct BPF_TIMEVAL *_tv = (struct BPF_TIMEVAL *)addr;
			struct timeval tv;

			tv.tv_sec  = _tv->tv_sec;
			tv.tv_usec = _tv->tv_usec;

			/*
			 * Subtract 1 tick from tvtohz() since this isn't
			 * a one-shot timer.
			 */
			if ((error = itimerfix(&tv)) == 0)
				d->bd_rtout = tvtohz(&tv) - 1;
			break;
		}

	/*
	 * Get read timeout.
	 */
	case BIOCGRTIMEOUT:
		{
			struct BPF_TIMEVAL *tv = (struct BPF_TIMEVAL *)addr;

			tv->tv_sec = d->bd_rtout / hz;
			tv->tv_usec = (d->bd_rtout % hz) * tick;
			break;
		}

	/*
	 * Get packet stats.
	 */
	case BIOCGSTATS:
		{
			struct bpf_stat *bs = (struct bpf_stat *)addr;

			bs->bs_recv = d->bd_rcount;
			bs->bs_drop = d->bd_dcount;
			break;
		}

	/*
	 * Set immediate mode.
	 */
	case BIOCIMMEDIATE:
		d->bd_immediate = *(u_int *)addr;
		break;

	case BIOCVERSION:
		{
			struct bpf_version *bv = (struct bpf_version *)addr;

			bv->bv_major = BPF_MAJOR_VERSION;
			bv->bv_minor = BPF_MINOR_VERSION;
			break;
		}

	/*
	 * Get "header already complete" flag
	 */
	case BIOCGHDRCMPLT:
		*(u_int *)addr = d->bd_hdrcmplt;
		break;

	/*
	 * Set "header already complete" flag
	 */
	case BIOCSHDRCMPLT:
		d->bd_hdrcmplt = *(u_int *)addr ? 1 : 0;
		break;

	/*
	 * Get "see sent packets" flag
	 */
	case BIOCGSEESENT:
		*(u_int *)addr = d->bd_seesent;
		break;

	/*
	 * Set "see sent packets" flag
	 */
	case BIOCSSEESENT:
		d->bd_seesent = *(u_int *)addr;
		break;

	case FIONBIO:		/* Non-blocking I/O */
		break;

	case FIOASYNC:		/* Send signal on receive packets */
		d->bd_async = *(int *)addr;
		break;
#ifndef __APPLE__
	case FIOSETOWN:
		error = fsetown(*(int *)addr, &d->bd_sigio);
		break;

	case FIOGETOWN:
		*(int *)addr = fgetown(d->bd_sigio);
		break;

	/* This is deprecated, FIOSETOWN should be used instead. */
	case TIOCSPGRP:
		error = fsetown(-(*(int *)addr), &d->bd_sigio);
		break;

	/* This is deprecated, FIOGETOWN should be used instead. */
	case TIOCGPGRP:
		*(int *)addr = -fgetown(d->bd_sigio);
		break;
#endif
	case BIOCSRSIG:		/* Set receive signal */
		{
		 	u_int sig;

			sig = *(u_int *)addr;

			if (sig >= NSIG)
				error = EINVAL;
			else
				d->bd_sig = sig;
			break;
		}
	case BIOCGRSIG:
		*(u_int *)addr = d->bd_sig;
		break;
	}
	
	lck_mtx_unlock(bpf_mlock);

	return (error);
}
int
soo_ioctl(file_t *fp, u_long cmd, void *data)
{
	struct socket *so = fp->f_data;
	int error = 0;

	switch (cmd) {

	case FIONBIO:
		solock(so);
		if (*(int *)data)
			so->so_state |= SS_NBIO;
		else 
			so->so_state &= ~SS_NBIO; 
		sounlock(so);
		break;

	case FIOASYNC:
		solock(so);
		if (*(int *)data) {
			so->so_state |= SS_ASYNC;
			so->so_rcv.sb_flags |= SB_ASYNC;
			so->so_snd.sb_flags |= SB_ASYNC;
		} else {
			so->so_state &= ~SS_ASYNC;
			so->so_rcv.sb_flags &= ~SB_ASYNC;
			so->so_snd.sb_flags &= ~SB_ASYNC;
		}
		sounlock(so);
		break;

	case FIONREAD:
		*(int *)data = so->so_rcv.sb_cc;
		break;

	case FIONWRITE:
		*(int *)data = so->so_snd.sb_cc;
		break;

	case FIONSPACE:
		/*
		 * See the comment around sbspace()'s definition
		 * in sys/socketvar.h in face of counts about maximum
		 * to understand the following test. We detect overflow
		 * and return zero.
		 */
		solock(so);
		if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc)
		    || (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt))
			*(int *)data = 0;
		else
			*(int *)data = sbspace(&so->so_snd);
		sounlock(so);
		break;

	case SIOCSPGRP:
	case FIOSETOWN:
	case TIOCSPGRP:
		error = fsetown(&so->so_pgid, cmd, data);
		break;

	case SIOCGPGRP:
	case FIOGETOWN:
	case TIOCGPGRP:
		error = fgetown(so->so_pgid, cmd, data);
		break;

	case SIOCATMARK:
		*(int *)data = (so->so_state&SS_RCVATMARK) != 0;
		break;

	default:
		/*
		 * Interface/routing/protocol specific ioctls:
		 * interface and routing ioctls should have a
		 * different entry since a socket's unnecessary
		 */
		KERNEL_LOCK(1, NULL);
		if (IOCGROUP(cmd) == 'i')
			error = ifioctl(so, cmd, data, curlwp);
		else if (IOCGROUP(cmd) == 'r')
			error = rtioctl(cmd, data, curlwp);
		else {
			error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
			    (struct mbuf *)cmd, (struct mbuf *)data, NULL,
			     curlwp);
		}
		KERNEL_UNLOCK_ONE(NULL);
		break;
	}


	return error;
}