/* Copyright 1987 by the Massachusetts Institute of Technology */
/* See permission and disclaimer notice in file notice.h */
#include	<notice.h>

/* A Multiplexing network.  This is a pseudo network for combining
 * several nets into a single net for routing purposes.  The initial
 * use it was written for was to make several serial line nets look
 * like a single IP subnet.
 */

/*
 *------------------------------------------------------------------
 *
 * $Source: /mit/cgw/src/gw/nets/RCS/mux.c,v $
 * $Revision: 1.1 $
 * $Date: 88/06/05 22:37:24 $
 * $State: Exp $
 * $Author: jon $
 * $Locker: jon $
 *
 * $Log:	mux.c,v $
 * Revision 1.1  88/06/05  22:37:24  jon
 * Initial revision
 * 
 *------------------------------------------------------------------
 */

#ifndef lint
static char *rcsid_param_c = "$Header: mux.c,v 1.1 88/06/05 22:37:24 jon Locked $";
#endif	lint

#include	<types.h>
#include	<sys.h>
#include	"../src/const.h"
#include	"../src/param.h"
#include	"../src/defs.h"
#include	"../src/macs.h"
#include	"../src/net.h"
#include	"../src/ext.h"
#include	"../in/in.h"
#include	"../dev.vax/dhv.h"

/* Protocol initialization.  Currently this is only implemented for
 * IP.  It should be easy to extend it for use with other protocols
 * should that be desired.  The configuration structure is quite IP
 * specific but if it could be changed to be indexed by protocol type
 * as well as network number.
 */
mux_pinit(netp, prot, nm)
net *netp;
unsw prot;
word nm;
{
    if (netp->n_type != ((unsb)T_MUX))
      bughalt("mux_prinit called but not a MUX net");

    if (prot != P_IN)
      bughalt("Protocol for MUX was not IP");
}

/* The send routine.  This routes to the correct actual net based on
 * the address and passes the packet off to there.  The routing
 * algorithm is simply to use the low byte of the IP address as an
 * index into the MUX net's routing configuration.  The routing
 * configuration is just a byte array the entries of which are net
 * numbers.  The first entry is a count of the number of following
 * entries.  Note that this disallows host 0.
 */
mux_out(iob, netp, prot, nm)
iorb *iob;
net *netp;
unsw prot;
word nm;
{
    unsb len;
    unsb addr;
    extern unsb mux_rte[];

    if (prot != P_IN)
      bughalt("mux_out called but not IP");

    len = mux_rte[0];
    addr = mkina(nm)->i_byte.i_bytel;
    if ((addr > len) || addr == 0)
      return D_ERR;
    netp = &nets[mux_rte[addr]];
    return (*netp->n_send)(iob, netp, prot, nm);
}
