/*
 * @DEC_COPYRIGHT@
 */
/*
 * HISTORY
 * $Log:	dli_proto.c,v $
 * Revision 4.3.3.4  92/06/01  16:53:49  Benjamin_England
 * 	merge final DECnet-ULTRIX and OSF versions
 * 	[92/05/15  11:28:23  Benjamin_England]
 * 
 * 	support kernel builds without DLI option
 * 	dli_proto.c becomes Notbinary, always compiles
 * 	[92/05/15  11:18:25  Benjamin_England]
 * 
 * Revision 4.3.3.3  92/06/01  16:09:32  Benjamin_England
 * 	add new dli_multi_op_fp function for passing NETMAN multicast info
 * 	avoid integer-ptr conversion
 * 	[92/05/20  10:03:17  Benjamin_England]
 * 
 * 	fix bugs
 * 	[92/05/14  09:12:43  Benjamin_England]
 * 
 * Revision 4.3.3.2  92/03/26  15:26:51  Benjamin_England
 * 	"DECnet/DLI hooks"
 * 
 * Revision 4.3.5.2  92/05/14  09:12:43  Benjamin_England
 * 	fix bugs
 * 
 * Revision 4.3.3.2  92/03/26  15:26:51  Benjamin_England
 * 	"DECnet/DLI hooks"
 * 
 * Revision 4.3.2.3  92/03/26  15:00:55  Benjamin_England
 * 	did merge with NEW
 * 
 * Revision 4.3.2.2  92/03/26  09:52:48  Benjamin_England
 * 	fix set problem
 * 
 * Revision 4.3.1.4  92/03/20  10:36:40  Benjamin_England
 * 	change #ifdef NETMAN to #if NETMAN
 * 	add another NETMAN function pointer
 * 
 * Revision 4.3.1.3  92/03/18  17:36:42  Benjamin_England
 * 	set function pointers to zero unless NETMAN installed
 * 
 * Revision 4.3.1.2  92/03/18  17:06:13  Benjamin_England
 * 	add support for optional use of NETMAN subset
 * 	add in protocol switch table entries which are used by AF_OSI
 * 
 * Revision 4.3  91/11/26  11:09:12  devbld_zk3
 * 	Baselevel AG_BL0
 * 
 * Revision 4.2.2.2  91/11/05  10:33:06  William_Burns
 * 	Merge from ODE/TIN: revision 3.1.9.2
 * 	date: 91/10/24 16:28:42;  author: devrcs;  state: Exp;  lines added/del: 43/4
 * 	sccs rev: 3.2;  orig date: 91/10/10 14:07:44;  orig author: thomas
 * 	Fix outstanding QARs.
 * 	Add FDDI support
 * 	Fix sysid generation
 * 	Fix ethernet loopback.
 * 	Fix 802 packet parsing.
 * 	[91/10/29  10:15:44  William_Burns]
 * 
 * Revision 4.2  91/09/19  23:29:36  devbld
 * 	Adding ODE Headers
 * 
 * $EndLog$
 */
#ifndef	lint
static char *sccsid = "@(#)$RCSfile: dli_proto.c,v $ $Revision: 4.3.3.4 $ (DEC) $Date: 92/06/01 16:53:49 $";
#endif	lint

/*
 * Program dli_proto.c,  Module DLI 
 *
 * Copyright (C) 1985 by
 * Digital Equipment Corporation, Maynard, Mass.
 *
 * This software is furnished under a license and may be used and copied
 * only  in  accordance  with  the  terms  of such  license and with the
 * inclusion of the above copyright notice. This software or  any  other
 * copies thereof may not be provided or otherwise made available to any
 * other person. No title to and ownership of  the  software  is  hereby
 * transferred.
 *
 * The information in this software is subject to change without  notice
 * and  should  not be  construed  as  a commitment by Digital Equipment
 * Corporation.
 *
 * Digital assumes no responsibility for the use or  reliability  of its
 * software on equipment which is not supplied by Digital.
 *
 *
 * Networks & Communications Software Engineering
 *
 * IDENT HISTORY:
 *
 * 1.00 10-Jul-1985
 *      DECnet-ULTRIX   V1.0
 *
 * 2.00 18-Apr-1986
 *		DECnet-Ultrix	V2.0
 *
 * 5.00 09-Oct-1989
 *		DECnet-Ultrix	V5.0
 *
 * Added sysid and point-to-point support
 *
 */


#include <sys/param.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/domain.h>
#include <sys/mbuf.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <dli/dli_var.h>
#include <dli.h>

#if DLI > 0

#if	MACH
#include <sys/sysconfig.h>
#include <kern/parallel.h>
#endif

#if NETMAN > 0

extern void csmacd_init(),csmacd_input(),csmacd_ctlinput();
extern int csmacd_ctloutput(),csmacd_output();

extern void fddi_init(),fddi_ctlinput(),fddi_input();
extern int fddi_ctloutput(),fddi_output();

/**** #include <trn.h>	uncomment when token ring is real 
extern void trn_init(),trn_input(),trn_ctlinput();
extern int trn_ctloutput(),trn_output();
***********/

extern void dloop_init(),dloop_input();
extern int dloop_ctloutput(),dloop_output();

#endif /* NETMAN */

/* these function pointers only exist so that base system DLI can
 * quickly and efficiently detect when additional DLI code for NETMAN
 * support is present
 */
#if NETMAN > 0

CONST caddr_t (* dli_openport_fp )() = dli_openport;
CONST int (* dli_prco_pif_fp )() = dli_prco_pif;
CONST int (* dli_name2if_fp )() = dli_name2if;
CONST void (* dli_sysid_extra_fp )() = dli_sysid_extra;
CONST int (* dli_output_netman_fp)() = dli_output_netman;
CONST int (* dli_multi_op_fp)() = dli_multi_op;

#else

/* set them to zero so base system DLI won't try to call them */
CONST caddr_t (* dli_openport_fp )() = NULL;
CONST int (* dli_prco_pif_fp )() = NULL;
CONST int (* dli_name2if_fp )() = NULL;
CONST void (* dli_sysid_extra_fp )() = NULL;
CONST int (* dli_output_netman_fp)() = NULL;
CONST int (* dli_multi_op_fp)() = NULL;

#endif /* NETMAN */

/*
 * Definitions of protocols supported in the DLI domain.
 */
int dli_ifq_maxlen = 32;
int dli_mustberoot = 1;
u_int dli_maxline = DLI * 32;
struct dli_line dli_ltable[DLI * 32]; 		/* DLI line table */

dli_config()
{
    return domain_add(&dlidomain);
}

extern int dli_usrreq(), dli_ctloutput();
extern void dli_init(), dli_slowtimo(), dli_ctlinput();
extern void dli_funnel();

struct protosw dlisw[] = {
    {	SOCK_DGRAM,	&dlidomain,	DLPROTO_DLI,	PR_ATOMIC|PR_ADDR,
	0,		0,		dli_ctlinput,	dli_ctloutput,
	dli_usrreq,	dli_init,	0,		dli_slowtimo,
	0,
    },
#if NETMAN > 0
    { SOCK_DGRAM,     &dlidomain,       DLPROTO_CSMACD,  PR_ATOMIC | PR_ADDR,
      csmacd_input,   csmacd_output,    csmacd_ctlinput, csmacd_ctloutput,
      0,              csmacd_init,      0,               0,
      0
    },
    { SOCK_DGRAM,     &dlidomain,       DLPROTO_FDDI,	 PR_ATOMIC | PR_ADDR,
      fddi_input,     fddi_output,      fddi_ctlinput,   fddi_ctloutput,
      0,              fddi_init,        0,               0,
      0
    },
/************* future token ring support 
    { SOCK_DGRAM,     &dlidomain,       DLPROTO_TRN,	 PR_ATOMIC | PR_ADDR,
      trn_input,      trn_output,       trn_ctlinput,    trn_ctloutput,
      0,              trn_init,         0,               0,
      0
    },
****************/
    { SOCK_DGRAM,     &dlidomain,       DLPROTO_LOOP,	 PR_ATOMIC | PR_ADDR,
      0,              dloop_output,     0,               dloop_ctloutput,
      0,              dloop_init,       0,               0,
      0
    },
#endif /* NETMAN */
};


/*
 * DLI has not been modified for parallelization, and is
 * thus unconditionally funneled with raised spl by the
 * socket layer from above and the netisr's from below.
 */

static void
dli_sanity()
{
	panic("dli unfunnel");
}

static void
dli_unfunnel(dfp)
	struct domain_funnel *dfp;
{
	dfp->unfunnel = dli_sanity;
	NETSPLX(dfp->object.spl);
	unix_release();
}

/* this routine is also called by the NETMAN subset */
void
dli_funnel(dfp)
	struct domain_funnel *dfp;
{
	if (dfp->unfunnel)
		panic("dli funnel");
	dfp->unfunnel = dli_unfunnel;
	unix_master();
	NETSPL(dfp->object.spl, net);
}

struct domain dlidomain = {
    AF_DLI,  "DLI", 0, 0, 0,
    dlisw, &dlisw[sizeof(dlisw)/sizeof(dlisw[0])],
    0, 0, dli_funnel, 0 };

#else /* #if DLI == 0 */

/* this routine must exist whether DLI is in kernel or not, so that
 * netinit() can call it, since netisr.c is not recompiled for different
 * flavors of kernel
 */
dli_config()
{
    return 0;
}

#endif /* DLI */

