static char rcsid[] = "$Header: vnet.c,v 800.4 86/07/10 20:25:36 root Exp $";
static char sccsid[]="%W% %Y% %Q% %G%";

/************************************************************************
 *									*
 *				Copyright 1985				*
 *			VALID LOGIC SYSTEMS INCORPORATED		*
 *									*
 *	This listing contains confidential proprietary information	*
 *	which is not to be disclosed to unauthorized persons without	*
 *	written consent of an officer of Valid Logic Systems 		*
 *	Incoroporated.							*
 *									*
 *	The copyright notice appearing above is included to provide	*
 *	statutory protection in the event of unauthorized or 		*
 *	unintentional public disclosure.				*
 *									*
 ************************************************************************/

/*
 * i/o controls for VALIDnet protocols.
 * sas 850423
 */

#include "../h/param.h"
#include "../h/systm.h"		/* For C_WAIT */
#include "../h/errno.h"
#include "../h/ioctl.h"
#include "../h/mbuf.h"
#include "../h/socket.h"
#include "../net/af.h"
#include "../net/if.h"
#include "../netinet/if_ether.h"
#include "../vnet/vnet.h"
#include "../vnet/vnet_ioctl.h"


short vnetinited = 0;

/*
 * vnetioctl --
 *	Handle i/o controls from soioctl()
 */
vnetioctl(cmd, data)
	int cmd;
	caddr_t data;
{
	int s;

	switch (cmd) {
	case VNETIOC_SET:
		{
		extern struct ifnet *ifconn;
		extern struct ifnet *ifrpc;
#ifdef VALID_BULK
		extern struct ifnet *ifbulk;
#endif VALID_BULK
		extern struct ifnet *ifunit();
		/*
		 * The user may initialize his VALIDnet interface
		 * exactly once per generation.  This allows
		 * us to ignore what would happen if we changed
		 * interfaces during VALIDnet connections with other systems.
		 */
		register struct vnetconf *v = (struct vnetconf *)data;
		register struct ifnet *ifconn_new = (struct ifnet *)0;
		register struct ifnet *ifrpc_new = (struct ifnet *)0;
#ifdef VALID_BULK
		register struct ifnet *ifbulk_new = (struct ifnet *)0;
#endif VALID_BULK
		extern node_t myNode;

		ifconn_new = ifunit(v->ifconnname);
		ifrpc_new = ifunit(v->ifrpcname);
#ifdef VALID_BULK
		ifbulk_new = ifunit(v->ifbulkname);
#endif VALID_BULK
		if (!ifconn_new || 
#ifdef VALID_BULK
				!ifbulk_new ||
#endif VALID_BULK
				!ifrpc_new)
			return EADDRNOTAVAIL;
		if (ifconn_new->if_addr.sa_family != AF_CONN ||
#ifdef VALID_BULK
		    ifbulk_new->if_addr.sa_family != AF_BULK ||
#endif VALID_BULK
		    ifrpc_new->if_addr.sa_family != AF_RPC)
			return EINVAL;

		if (vnetinited) {
			if (ifconn == ifconn_new && ifrpc == ifrpc_new)
				return 0;
			else
				return EIO;
		}


		s = splimp();
		ifconn = ifconn_new;
		ifrpc = ifrpc_new;
#ifdef VALID_BULK
		ifbulk = ifbulk_new;
#endif VALID_BULK
		/*
		 * This changes the RPC-used myNode variable
		 * SIDE EFFECTS!!!
		 */
		myNode = ((struct sockaddr_vnet *)&ifrpc->if_addr)->sa_node;
		vnetinited++;
		splx(s);
		}
		break;

	default:
		return EOPNOTSUPP;
	}
	return 0;
}
