FreeBSD/sys/net/if_tap.c
/*
 * tapioctl
 *
 * the cdevsw interface is now pretty minimal
 */
tapioctl
the cdevsw interface is now pretty minimal
tapioctl the cdevsw interface is now pretty minimal
static int
tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
{
	struct tap_softc	*tp = dev->si_drv1;
	struct ifnet		*ifp = tp->tap_ifp;
	struct tapinfo		*tapp = NULL;
	int			 f;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4)
	int			 ival;
#endif
	switch (cmd) {
		case TAPSIFINFO:
			tapp = (struct tapinfo *)data;
			mtx_lock(&tp->tap_mtx);
			ifp->if_mtu = tapp->mtu;
			ifp->if_type = tapp->type;
			ifp->if_baudrate = tapp->baudrate;
			mtx_unlock(&tp->tap_mtx);
			break;
		case TAPGIFINFO:
			tapp = (struct tapinfo *)data;
			mtx_lock(&tp->tap_mtx);
			tapp->mtu = ifp->if_mtu;
			tapp->type = ifp->if_type;
			tapp->baudrate = ifp->if_baudrate;
			mtx_unlock(&tp->tap_mtx);
			break;
		case TAPSDEBUG:
			tapdebug = *(int *)data;
			break;
		case TAPGDEBUG:
			*(int *)data = tapdebug;
			break;
		case TAPGIFNAME: {
			struct ifreq	*ifr = (struct ifreq *) data;
			strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ);
			} break;
		case FIONBIO:
			break;
		case FIOASYNC:
			mtx_lock(&tp->tap_mtx);
			if (*(int *)data)
				tp->tap_flags |= TAP_ASYNC;
			else
				tp->tap_flags &= ~TAP_ASYNC;
			mtx_unlock(&tp->tap_mtx);
			break;
		case FIONREAD:
			if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
				struct mbuf *mb;
				IFQ_LOCK(&ifp->if_snd);
				IFQ_POLL_NOLOCK(&ifp->if_snd, mb);
				for (*(int *)data = 0; mb != NULL;
				     mb = mb->m_next)
					*(int *)data += mb->m_len;
				IFQ_UNLOCK(&ifp->if_snd);
			} else
				*(int *)data = 0;
			break;
		case FIOSETOWN:
			return (fsetown(*(int *)data, &tp->tap_sigio));
		case FIOGETOWN:
			*(int *)data = fgetown(&tp->tap_sigio);
			return (0);
		case TIOCSPGRP:
			return (fsetown(-(*(int *)data), &tp->tap_sigio));
		case TIOCGPGRP:
			*(int *)data = -fgetown(&tp->tap_sigio);
			return (0);
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4)
		case _IO('V', 0):
			ival = IOCPARM_IVAL(data);
			data = (caddr_t)&ival;
#endif
		case VMIO_SIOCSIFFLAGS: 
			f = *(int *)data;
			f &= 0x0fff;
			f &= ~IFF_CANTCHANGE;
			f |= IFF_UP;
			mtx_lock(&tp->tap_mtx);
			ifp->if_flags = f | (ifp->if_flags & IFF_CANTCHANGE);
			mtx_unlock(&tp->tap_mtx);
			break;
		case SIOCGIFADDR:	
			mtx_lock(&tp->tap_mtx);
			bcopy(tp->ether_addr, data, sizeof(tp->ether_addr));
			mtx_unlock(&tp->tap_mtx);
			break;
		case SIOCSIFADDR:	
			mtx_lock(&tp->tap_mtx);
			bcopy(data, tp->ether_addr, sizeof(tp->ether_addr));
			mtx_unlock(&tp->tap_mtx);
			break;
		default:
			return (ENOTTY);
	}
	return (0);
}
static int tapioctl ( struct cdev * dev , u_long cmd , caddr_t data , int flag , struct thread * td ) { struct tap_softc * tp = dev -> si_drv1 ; struct ifnet * ifp = tp -> tap_ifp ; struct tapinfo * tapp = NULL ; int f ; #if defined ( COMPAT_FREEBSD6 ) || defined ( COMPAT_FREEBSD5 ) || defined ( COMPAT_FREEBSD4 ) int ival ; #endif switch ( cmd ) { case TAPSIFINFO : tapp = ( struct tapinfo * ) data ; mtx_lock ( & tp -> tap_mtx ) ; ifp -> if_mtu = tapp -> mtu ; ifp -> if_type = tapp -> type ; ifp -> if_baudrate = tapp -> baudrate ; mtx_unlock ( & tp -> tap_mtx ) ; break ; case TAPGIFINFO : tapp = ( struct tapinfo * ) data ; mtx_lock ( & tp -> tap_mtx ) ; tapp -> mtu = ifp -> if_mtu ; tapp -> type = ifp -> if_type ; tapp -> baudrate = ifp -> if_baudrate ; mtx_unlock ( & tp -> tap_mtx ) ; break ; case TAPSDEBUG : tapdebug = * ( int * ) data ; break ; case TAPGDEBUG : * ( int * ) data = tapdebug ; break ; case TAPGIFNAME : { struct ifreq * ifr = ( struct ifreq * ) data ; strlcpy ( ifr -> ifr_name , ifp -> if_xname , IFNAMSIZ ) ; } break ; case FIONBIO : break ; case FIOASYNC : mtx_lock ( & tp -> tap_mtx ) ; if ( * ( int * ) data ) tp -> tap_flags |= TAP_ASYNC ; else tp -> tap_flags &= ~ TAP_ASYNC ; mtx_unlock ( & tp -> tap_mtx ) ; break ; case FIONREAD : if ( ! IFQ_IS_EMPTY ( & ifp -> if_snd ) ) { struct mbuf * mb ; IFQ_LOCK ( & ifp -> if_snd ) ; IFQ_POLL_NOLOCK ( & ifp -> if_snd , mb ) ; for ( * ( int * ) data = 0 ; mb != NULL ; mb = mb -> m_next ) * ( int * ) data += mb -> m_len ; IFQ_UNLOCK ( & ifp -> if_snd ) ; } else * ( int * ) data = 0 ; break ; case FIOSETOWN : return ( fsetown ( * ( int * ) data , & tp -> tap_sigio ) ) ; case FIOGETOWN : * ( int * ) data = fgetown ( & tp -> tap_sigio ) ; return ( 0 ) ; case TIOCSPGRP : return ( fsetown ( - ( * ( int * ) data ) , & tp -> tap_sigio ) ) ; case TIOCGPGRP : * ( int * ) data = - fgetown ( & tp -> tap_sigio ) ; return ( 0 ) ; #if defined ( COMPAT_FREEBSD6 ) || defined ( COMPAT_FREEBSD5 ) || defined ( COMPAT_FREEBSD4 ) case _IO ( ' ' , 0 ) : ival = IOCPARM_IVAL ( data ) ; data = ( caddr_t ) & ival ; #endif case VMIO_SIOCSIFFLAGS : f = * ( int * ) data ; f &= 0x0fff ; f &= ~ IFF_CANTCHANGE ; f |= IFF_UP ; mtx_lock ( & tp -> tap_mtx ) ; ifp -> if_flags = f | ( ifp -> if_flags & IFF_CANTCHANGE ) ; mtx_unlock ( & tp -> tap_mtx ) ; break ; case SIOCGIFADDR : mtx_lock ( & tp -> tap_mtx ) ; bcopy ( tp -> ether_addr , data , sizeof ( tp -> ether_addr ) ) ; mtx_unlock ( & tp -> tap_mtx ) ; break ; case SIOCSIFADDR : mtx_lock ( & tp -> tap_mtx ) ; bcopy ( data , tp -> ether_addr , sizeof ( tp -> ether_addr ) ) ; mtx_unlock ( & tp -> tap_mtx ) ; break ; default : return ( ENOTTY ) ; } return ( 0 ) ; }
tapioctl
 the cdevsw interface is now pretty minimal
tapioctl the cdevsw interface is now pretty minimal
/* this is deprecated, FIOSETOWN should be used instead */ /* this is deprecated, FIOGETOWN should be used instead */ /* VMware/VMnet port ioctl's */ /* FALLTHROUGH */ /* VMware/VMnet SIOCSIFFLAGS */ /* get MAC address of the remote side */ /* set MAC address of the remote side */