READ_ME                                                                                                664     540       2         6103  3372247640   5110                                                                                                                                                                                                                                                                                                                                                                      To install the Serial Line IP mods to a 4.2BSD vax or sun do the following:

	1) In the file /sys/h/ioctl.h add the following defines:
	    (I am assuming that 5 and 21 are unused in your configuration)
	    (For Suns, use 7 instead of 5; 5 is used already.)

		#define SLIPDISC	5
		#define SIOCIFDETACH	_IOW(i, 21, struct ifreq)	/* detach interface */

	2) Compile ./src/etc/slattach.c and ./src/etc/sldetach.c and put
		the binaries in /etc.

		(cc -o /etc/slattach slattach.c)
		(cc -o /etc/sldetach sldetach.c)

	3) Replace /usr/src/ucb/netstat/if.c with src/ucb/netstat/if.c
   	    and make netstat. Put the binary in /usr/ucb in
	    place of the existing one (This is not necessary, but
	    is advised. The only difference is that if it is a
	    point-to-point link, it prints the destination address of the
	    link instead of the origin. This is what you would normally
	    want).
		(cd ./src/ucb/netstat;make;cp netstat /usr/ucb)

	4) Now for the kernel mods. Copy the Serial line driver to the
	    main source directory.
		(cp sys/vaxif/if_sl.c /sys/[vax|sun]if)

	5) replace /sys/net/route.c with ./sys/net/route.c.
	    This routine was changed to permit routing on one logical
    	    network with many physical networks.

	6) Add the serial line discipline to the linesw table in
	    /sys/sys/tty_conf.c(using ./sys/sys/tty_conf.c.machine as an example).
	    Or, if you have not modified your tty_conf.c, you can
	    copy the one from ./sys/sys/tty_conf.c..[vax|sun]
	    (You should diff them in any case).

	7) cd to /sys/conf. add the following line to files.[vax|sun]:
		[vax|sun]if/if_sl.c	optional sl device driver

	8) edit the config file for your machine and add the line:
		pseudo-device sl 2
	   This says you will use up to 2 physical interfaces. (It's
	   just a table size). You can make it smaller or larger to
	   suit your configuration.

	9) reconfigure and remake the kernel.
		(config machinename;cd ../machinename;make depend;make)
	   If you are doing this for a sun, "make depend" will complain about
	   not finding locore.s.  Ignore it. Also make depend will not
	   recognize #ifdef's and so will include a dependency of ../vax/mptr.h
	   for if_sl.o.  You have to edit the makefile to get rid of this,
	   about the fifth line from the bottom.

	10) reboot the new kernel.

	11) make sure that there is no getty running on the selected line
	    (ttyh0 for example). If there is nothing running, do:

		/etc/slattach ttyh0 source-address destination-address

	    If all goes well, you should be able to see the interface
	    with netstat. Normally, you would place the /etc/slattach in
	    /etc/rc.local right after the ifconfigs at the beginning.

	If you have problems with slattach not returning, make sure that
	there is carrier on the port. You may have to jumper it on.

	It should now be up and running. This has only been tested on a
	DH and a DZ but the code is there for a DMF as well.

	Feel free to call if you have problems.

	Rick Adams
	Center for Seismic Studies
	1300 N17th Street, Suite 1450
	Arlington, Virginia 22209
	(703)276-7900
	rick@seismo.ARPA
	seismo!rick

/slattach in
	    /etc/rc.local right after the ifconfigs at the beginning.

	If you have problems with slattach not returning, make sure that
	there is carrier on the port. You may have to jumper it on.

	It should now be up and running. This has only been tested on a
	DH and a DZ but the code is there for a DMF as well.

	Feel free to call if you have problems.

	Rick Adams
	Center for Seismic Studies
	1300 N17th Street, Suite 1450
	Arlingsrc/                                                                                                   775     540       2            0  3372246760   4575                                                                                                                                                                                                                                                                                                                                                                      src/etc/                                                                                               775     540       2            0  3372246760   5350                                                                                                                                                                                                                                                                                                                                                                      src/etc/slattach.c                                                                                     444     540       2         7356  3360561566   7414                                                                                                                                                                                                                                                                                                                                                                      #include <stdio.h>
#include <sys/types.h>
#include <sgtty.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netdb.h>
#include <fcntl.h>

#ifndef lint
static char	*RcsId = "$Header: slattach.c,v 1.1 84/10/04 12:57:12 rick Exp $";
#endif !lint

struct	ifreq ifr;
struct	sockaddr_in sin = { AF_INET };

int wantbaud = 9600;	/* default speed */
int speed;
int slipdisc = SLIPDISC;

char devname[32];
char hostname[32];

main(argc,argv)
char *argv[];
{
	register FILE *fp;
	register int fd;
	struct sgttyb sgtty;
	register char *dev = argv[1];
	int n;

	if (argc < 2 || argc > 5){
		fprintf(stderr,"usage: slattach ttyname source-name destination-name [baudrate]\n");
		exit(1);
	}

	if (argc == 5)
		wantbaud = atoi(argv[4]);

	speed = findspeed(wantbaud);
	if (speed == 0){
		fprintf(stderr,"%s: Unknown speed\n",argv[4]);
		exit(1);
	}
	if (strncmp("/dev/",dev,5)) {
		sprintf(devname,"/dev/%s",dev);
		dev = devname;
	}
	if ((fd=open(dev,O_RDWR|O_NDELAY)) < 0 ){
		perror(dev);
		exit(1);
	}

	if (ioctl(fd,TIOCGETP,&sgtty) < 0){
		perror(dev);
		exit(1);
	}
	sgtty.sg_ispeed  = sgtty.sg_ospeed = speed;
	if (ioctl(fd,TIOCSETP,&sgtty) < 0){
		perror(dev);
		exit(1);
	}

	if (ioctl(fd,TIOCSETD,&slipdisc)<0){
		perror("cant set line discipline");
		exit(1);
	}

	if (ioctl(fd,TIOCGETD,&n)<0){
		perror("cant get line discipline");
		exit(1);
	}

	close(fd);

	fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd < 0) {
		perror("ifattach: socket");
		exit(1);
	}
	sprintf(ifr.ifr_name,"sl%d",n);

#ifdef sun
	/* This crap is necessary because sun changed the ioctl 
	 * handling so that SIOCSIFDSTADDR ONLY gets handed the
	 * value of ifr_data, not the whole ifr structure
	 * like any sane implementation would. This is clearly
	 * a mistake on their part.
	 * Fortunately, sizeof (caddr_t) == sizeof(sin.sin_addr.s_addr)
	 * if it's not on your machine, you lose.
	 */
	getaddr(argv[3], &sin);
	ifr.ifr_data = (caddr_t)sin.sin_addr.s_addr;
#else vax
	getaddr(argv[3], (struct sockaddr_in *)&ifr.ifr_dstaddr);
#endif vax
	if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
		perror("ioctl (SIOCSIFDSTADDR)");
		exit(1);
	}

	getaddr(argv[2],(struct sockaddr_in *)&ifr.ifr_addr);
	if (ioctl(fd, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
		perror("ioctl (SIOCSIFADDR)");
		exit(1);
	}

}

struct sg_spds {int sp_val, sp_name;} spds[] = {
#ifdef B50
	{  50,	 B50},
#endif
#ifdef B75
	{  75,	 B75},
#endif
#ifdef B110
	{ 110,	B110},
#endif
#ifdef B150
	{ 150,	B150},
#endif
#ifdef B200
	{ 200,	B200},
#endif
#ifdef B300
	{ 300,  B300},
#endif
#ifdef B600
	{600,	B600},
#endif
#ifdef B1200
	{1200, B1200},
#endif
#ifdef B1800
	{1800, B1800},
#endif
#ifdef B2000
	{2000, B2000},
#endif
#ifdef B2400
	{2400, B2400},
#endif
#ifdef B3600
	{3600, B3600},
#endif
#ifdef B4800
	{4800, B4800},
#endif
#ifdef B7200
	{7200, B7200},
#endif
#ifdef B9600
	{9600, B9600},
#endif
#ifdef EXTA
	{19200,EXTA},
#endif
	{0, 0}
};

findspeed(wantbaud)
register int wantbaud;
{
	register struct sg_spds *sp;

	sp = spds;

	while ( sp->sp_val && sp->sp_val != wantbaud)
		sp++;

	return sp->sp_name;
}

struct	in_addr inet_makeaddr();

getaddr(s, sin)
char *s;
struct sockaddr_in *sin;
{
	struct hostent *hp;
	struct netent *np;
	int val;

	bzero(sin, sizeof(struct sockaddr_in));
	hp = gethostbyname(s);
	if (hp) {
		sin->sin_family = hp->h_addrtype;
		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
		return;
	}
	np = getnetbyname(s);
	if (np) {
		sin->sin_family = np->n_addrtype;
		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
		return;
	}
	sin->sin_family = AF_INET;
	val = inet_addr(s);
	if (val != -1) {
		sin->sin_addr.s_addr = val;
		return;
	}
	val = inet_network(s);
	if (val != -1) {
		sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
		return;
	}
	fprintf(stderr, "%s: bad value\n", s);
	exit(1);
}

in->sin_family = hp->h_addrtype;
		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
		return;
	}
	np = getnetbyname(s);
	if (np) {
		sin->sin_family = np->n_addrtype;
		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
		return;
	}
	sin->sin_family = AF_INET;
	vsrc/etc/slattach.8c                                                                                    444     540       2         2663  3360561036   7470                                                                                                                                                                                                                                                                                                                                                                      .TH SLATTACH 8C "20 September 1984"
.UC 4
.SH NAME
slattach \- attach serial lines as network interfaces
.br
sldetach \- detach serial lines that have been slattached
.SH SYOPNSIS
.B /etc/slattach
ttyname source destination
[
.I baudrate
]
.br
.B /etc/sldetach
interface-name
.SH DESCRIPTION
.I Slattach
is used to assign a tty line
to a network interface.
.I Slattach
and to define the network source and destination addresses. The
.I ttyname
parameter is a string of the form ``ttyXX'', or ``/dev/ttyXX'', while
the source and destination are either host names present
in the host name data base,
.IR hosts (5),
or DARPA Internet addresses expressed in the Internet standard
``dot notation''.
The optional
.I baudrate
parameter is used to set the speed of the connection. If not specified, the
default of 9600 is used.
.PP
Only the super-user may attach or detach a network interface.
.PP
.I Sldetach
is used to remove the ttyline that is being used for IP from the network
tables and allow it to be used as a normal terminal again.
.I interface-name
is the name that is shown by
.B netstat(1)
.SH EXAMPLES
.ta 8
	/etc/slattach ttyh8 seismo osg3
.br
	/etc/slattach /dev/tty01 hugo dahl 4800
.br
	/etc/sldetach sl0
.SH DIAGNOSTICS
Messages indicating the specified interface does not exit, the
requested address is unknown, the user is not privileged and
tried to alter an interface's configuration.
.SH "SEE ALSO"
rc(8), intro(4N), netstat(1), ifconfig(8C)
used for IP from the network
tables and allow it to be used as a normal termisrc/etc/sldetach.c                                                                                     444     540       2         4617  3360561507   7370                                                                                                                                                                                                                                                                                                                                                                      #ifndef lint
static char	*RcsId = "$Header: sldetach.c,v 1.1 84/10/04 12:56:27 rick Exp $";
#endif !lint

#include <stdio.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/mbuf.h>
#include <nlist.h>

#define	KERNEL
#include <net/route.h>
#include <netinet/in.h>

struct	rtentry route;

struct nlist nl[] = {
#define	N_RTHOST	0
	{ "_rthost" },
#define	N_RTNET		1
	{ "_rtnet" },
	"",
};

struct	ifreq ifr;

main(argc,argv)
char *argv[];
{
	register struct rtentry *rt;
	register struct mbuf *m;
	register int fd;
	struct mbuf mb;
	struct mbuf *routehash[RTHASHSIZ];
	struct sockaddr_in *sin;
	struct in_addr deladdr;
	int i, doinghost = 1, kmem;

	if (argc != 2) {
		fprintf(stderr,"usage: sldetach interface-name\n");
		exit(1);
	}

	fd = socket(AF_INET, SOCK_DGRAM, 0);
	if (fd < 0) {
		perror("sldetach: socket");
		exit(1);
	}
	strcpy(ifr.ifr_name,argv[1]);

	/* We must flush entries in the routing tables that go
	 * through this interface. The network code gets very
	 * upset when the interface is gone and it thinks it
	 * has a route through it.
	 */
	if (ioctl(fd, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
		perror("ioctl (SIOCGIFADDR)");
		exit(1);
	}

	sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
	deladdr = sin->sin_addr;

	nlist("/vmunix", nl);
	if (nl[N_RTHOST].n_value == 0) {
		printf("sldetach: \"rthost\", symbol not in namelist\n");
		exit(1);
	}
	if (nl[N_RTNET].n_value == 0) {
		printf("sldetach: \"rtnet\", symbol not in namelist\n");
		exit(1);
	}

	kmem = open("/dev/kmem", 0);
	if (kmem < 0) {
		perror("route: /dev/kmem");
		exit(1);
	}
	lseek(kmem, nl[N_RTHOST].n_value, 0);
	read(kmem, routehash, sizeof (routehash));
again:
	for (i = 0; i < RTHASHSIZ; i++) {
		if (routehash[i] == 0)
			continue;
		m = routehash[i];
		while (m) {
			lseek(kmem, m, 0);
			read(kmem, &mb, sizeof (mb));
			rt = mtod(&mb, struct rtentry *);
			sin = (struct sockaddr_in *)&rt->rt_gateway;
			if (deladdr.s_addr == sin->sin_addr.s_addr) {
				if (ioctl(fd, SIOCDELRT, (caddr_t)rt) < 0)
					perror("delete");
			}
			m = mb.m_next;
		}
	}
	if (doinghost) {
		lseek(kmem, nl[N_RTNET].n_value, 0);
		read(kmem, routehash, sizeof (routehash));
		doinghost = 0;
		goto again;
	}
	close(kmem);

	/* Now that the routes have been removed, we can actually
	 * delete the interface
	 */
	if (ioctl(fd, SIOCIFDETACH, (caddr_t)&ifr) < 0) {
		perror("ioctl (SIOCIFDETACH)");
		exit(1);
	}
}
in *)&rt->rt_gateway;
			if (deladdr.s_addr == sin->sin_addr.s_addr) {
				if (ioctl(fd, SIOCDELRT, (caddr_t)rt) src/ucb/                                                                                               775     540       2            0  3372246760   5346                                                                                                                                                                                                                                                                                                                                                                      src/ucb/netstat/                                                                                       775     540       2            0  3372246760   7030                                                                                                                                                                                                                                                                                                                                                                      src/ucb/netstat/if.c                                                                                   444     540       2        11442  3354412465   7672                                                                                                                                                                                                                                                                                                                                                                      #ifndef lint
static char sccsid[] = "@(#)if.c	4.4 82/11/14";
#endif

#include <sys/types.h>
#include <sys/socket.h>

#include <net/if.h>
#include <netinet/in.h>

#include <stdio.h>

extern	int kmem;
extern	int tflag;
extern	int nflag;
extern	char *routename();

/*
 * Print a description of the network interfaces.
 */
intpr(interval, ifnetaddr)
	int interval;
	off_t ifnetaddr;
{
	struct ifnet ifnet;
	char name[16];

	if (ifnetaddr == 0) {
		printf("ifnet: symbol not defined\n");
		return;
	}
	if (interval) {
		sidewaysintpr(interval, ifnetaddr);
		return;
	}
	klseek(kmem, ifnetaddr, 0);
	read(kmem, &ifnetaddr, sizeof ifnetaddr);
	printf("%-5.5s %-5.5s %-10.10s  %-12.12s %-7.7s %-5.5s %-7.7s %-5.5s",
		"Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
		"Opkts", "Oerrs");
	printf(" %-6.6s", "Collis");
	if (tflag)
		printf(" %-6.6s", "Timer");
	putchar('\n');
	while (ifnetaddr) {
		struct sockaddr_in *sin;
		register char *cp;
		char *index();
		struct in_addr in, inet_makeaddr();

		klseek(kmem, ifnetaddr, 0);
		read(kmem, &ifnet, sizeof ifnet);
		klseek(kmem, (int)ifnet.if_name, 0);
		read(kmem, name, 16);
		name[15] = '\0';
		cp = index(name, '\0');
		*cp++ = ifnet.if_unit + '0';
		if ((ifnet.if_flags&IFF_UP) == 0)
			*cp++ = '*';
		*cp = '\0';
		printf("%-5.5s %-5d ", name, ifnet.if_mtu);
		if (ifnet.if_flags&IFF_POINTOPOINT)
			sin = (struct sockaddr_in *)&ifnet.if_dstaddr;
		else
			sin = (struct sockaddr_in *)&ifnet.if_addr;
		in = inet_makeaddr(ifnet.if_net, INADDR_ANY);
		printf("%-10.10s  ", routename(in));
		printf("%-12.12s %-7d %-5d %-7d %-5d %-6d",
		    routename(sin->sin_addr),
		    ifnet.if_ipackets, ifnet.if_ierrors,
		    ifnet.if_opackets, ifnet.if_oerrors,
		    ifnet.if_collisions);
		if (tflag)
			printf(" %-6d", ifnet.if_timer);
		putchar('\n');
		ifnetaddr = (off_t) ifnet.if_next;
	}
}

#define	MAXIF	10
struct	iftot {
	char	ift_name[16];		/* interface name */
	int	ift_ip;			/* input packets */
	int	ift_ie;			/* input errors */
	int	ift_op;			/* output packets */
	int	ift_oe;			/* output errors */
	int	ift_co;			/* collisions */
} iftot[MAXIF];

/*
 * Print a running summary of interface statistics.
 * Repeat display every interval seconds, showing
 * statistics collected over that interval.  First
 * line printed at top of screen is always cumulative.
 */
sidewaysintpr(interval, off)
	int interval;
	off_t off;
{
	struct ifnet ifnet;
	off_t firstifnet;
	extern char _sobuf[];
	register struct iftot *ip, *total;
	register int line;
	struct iftot *lastif, *sum, *interesting;
	int maxtraffic;

	setbuf(stdout, _sobuf);
	klseek(kmem, off, 0);
	read(kmem, &firstifnet, sizeof (off_t));
	lastif = iftot;
	sum = iftot + MAXIF - 1;
	total = sum - 1;
	for (off = firstifnet, ip = iftot; off;) {
		char *cp;

		klseek(kmem, off, 0);
		read(kmem, &ifnet, sizeof ifnet);
		klseek(kmem, (int)ifnet.if_name, 0);
		ip->ift_name[0] = '(';
		read(kmem, ip->ift_name + 1, 15);
		ip->ift_name[15] = '\0';
		cp = index(ip->ift_name, '\0');
		sprintf(cp, "%d)", ifnet.if_unit);
		ip++;
		if (ip >= iftot + MAXIF - 2)
			break;
		off = (off_t) ifnet.if_next;
	}
	lastif = ip;
	interesting = iftot;
banner:
	printf("    input   %-6.6s    output       ", interesting->ift_name);
	if (lastif - iftot > 0)
		printf("    input   (Total)    output       ");
	for (ip = iftot; ip < iftot + MAXIF; ip++) {
		ip->ift_ip = 0;
		ip->ift_ie = 0;
		ip->ift_op = 0;
		ip->ift_oe = 0;
		ip->ift_co = 0;
	}
	putchar('\n');
	printf("%-7.7s %-5.5s %-7.7s %-5.5s %-5.5s ",
		"packets", "errs", "packets", "errs", "colls");
	if (lastif - iftot > 0)
		printf("%-7.7s %-5.5s %-7.7s %-5.5s %-5.5s ",
			"packets", "errs", "packets", "errs", "colls");
	putchar('\n');
	fflush(stdout);
	line = 0;
loop:
	sum->ift_ip = 0;
	sum->ift_ie = 0;
	sum->ift_op = 0;
	sum->ift_oe = 0;
	sum->ift_co = 0;
	for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
		klseek(kmem, off, 0);
		read(kmem, &ifnet, sizeof ifnet);
		if (ip == interesting)
			printf("%-7d %-5d %-7d %-5d %-5d ",
				ifnet.if_ipackets - ip->ift_ip,
				ifnet.if_ierrors - ip->ift_ie,
				ifnet.if_opackets - ip->ift_op,
				ifnet.if_oerrors - ip->ift_oe,
				ifnet.if_collisions - ip->ift_co);
		ip->ift_ip = ifnet.if_ipackets;
		ip->ift_ie = ifnet.if_ierrors;
		ip->ift_op = ifnet.if_opackets;
		ip->ift_oe = ifnet.if_oerrors;
		ip->ift_co = ifnet.if_collisions;
		sum->ift_ip += ip->ift_ip;
		sum->ift_ie += ip->ift_ie;
		sum->ift_op += ip->ift_op;
		sum->ift_oe += ip->ift_oe;
		sum->ift_co += ip->ift_co;
		off = (off_t) ifnet.if_next;
	}
	if (lastif - iftot > 0)
		printf("%-7d %-5d %-7d %-5d %-5d\n",
			sum->ift_ip - total->ift_ip,
			sum->ift_ie - total->ift_ie,
			sum->ift_op - total->ift_op,
			sum->ift_oe - total->ift_oe,
			sum->ift_co - total->ift_co);
	*total = *sum;
	fflush(stdout);
	line++;
	if (interval)
		sleep(interval);
	if (line == 21)
		goto banner;
	goto loop;
	/*NOTREACHED*/
}
	sum->ift_ie += ip->ift_ie;
		sum->ift_op += ip->ift_op;
		sum->ift_oe += ip->ift_oe;
		sum->ift_co += ip->ift_co;
		off = (off_t) ifnet.if_next;
	}
	if (lastif - iftot > 0)
		printf("%-7d %-5d %-7d %-5d %-5d\n",
			sum->isys/                                                                                                   775     540       2            0  3372247257   4626                                                                                                                                                                                                                                                                                                                                                                      sys/vaxif/                                                                                             775     540       2            0  3372246761   5742                                                                                                                                                                                                                                                                                                                                                                      sys/vaxif/if_sl.c                                                                                      444     540       2        23710  3360561411   7273                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Serial Line interface
 *
 *	Rick Adams
 *	Center for Seismic Studies
 *	1300 N 17th Street, Suite 1450
 *	Arlington, Virginia 22209
 *	(703)276-7900
 *	rick@seismo.ARPA
 *	seismo!rick
 *
 *	Some things done here could obviously be done in a better way,
 *	but they were done this way to minimize the number of files
 *	that had to be changed to accomodate this device.
 *	A lot of this code belongs in the tty driver.
 */

static char rcsid[] = "$Header: if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp $";

#include "sl.h"
#if NSL > 0

#include "../h/param.h"
#include "../h/mbuf.h"
#include "../h/buf.h"
#include "../h/socket.h"
#include "../h/ioctl.h"
#include "../h/tty.h"
#include "../h/errno.h"

#include "../net/if.h"
#include "../net/netisr.h"
#include "../net/route.h"
#include "../netinet/in.h"
#include "../netinet/in_systm.h"
#include "../netinet/ip.h"
#include "../netinet/ip_var.h"

#ifdef vax
#include "../vax/mtpr.h"
#endif vax

struct sl_softc {
	struct	ifnet sc_if;		/* network-visible interface */
	short	sc_escaped;		/* flags */
	short	sc_oactive;		/* active or not */
	struct	tty *sc_ttyp;		/* pointer to tty structure */
	int	sc_ttyspeed;		/* baud rate of line */
	int	sc_len;			/* length of buffer remaining */
	struct mbuf *sc_m;		/* head of mbuf chain */
	struct mbuf *sc_mt;		/* tail of mbuf chain */
	u_char *sc_mp;			/* pointer to next available buf char */
}sl_softc[NSL];

#define FRAME_END	 	0300		/* Frame End */
#define FRAME_ESCAPE		0333		/* Frame Esc */
#define TRANS_FRAME_END	 	0334		/* transposed frame end */
#define TRANS_FRAME_ESCAPE 	0335		/* transposed frame esc */

#define SLTU	1006

#ifdef sun
#define T_LINEP	t_nlines
#endif

int sloutput(), slioctl();

slopen(dev,tp)
dev_t dev;
register struct tty *tp;
{
	register struct sl_softc *sc = sl_softc;
	register struct sockaddr_in *sin;
	register int nsl;
	extern int ifqmaxlen;
	int addloop = 0;

	if (tp->T_LINEP)
		return EBUSY;

	for(nsl = 0; sc->sc_ttyp; sc++)
		if(nsl++ >= NSL)
			return ENOSPC;

	/* This is a real kludge. Since we do the attach in the rc file,
	 * the loopback driver gets configured first. Now Berkeley, in its
	 * infinite wisdom, when connecting to a machine through a gateway,
	 * chooses the FIRST interface on its list. Guess what that is when you
	 * don't have an ethernet? That's right! It's the loopback driver!
	 * The following crock is an attempt to get around that.
	 */

	if (ifnet && ifnet->if_name[0] == 'l' && ifnet->if_name[1] == 'o'
		&& ifnet->if_name[2] == '\0') {
		/* the loopback device is configured in first */
		ifnet = ifnet->if_next;
		addloop++;
	}

	bzero((caddr_t)sc, sizeof(struct sl_softc));
#ifdef sun
	tp->T_LINEP = (int)sc;
#else vax
	tp->T_LINEP = (caddr_t)sc;
#endif vax
	sc->sc_ttyp = tp;
	sc->sc_if.if_unit = nsl;
	sc->sc_if.if_name = "sl";
	sc->sc_if.if_mtu = SLTU;
	sc->sc_if.if_output = sloutput;
	sc->sc_if.if_ioctl = slioctl;
	sc->sc_if.if_flags = IFF_POINTOPOINT;
	sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
	if_attach(&sc->sc_if);

	if (addloop)
		loattach();

	return 0;
}

/*ARGSUSED*/
sltioctl(tp, cmd, data, flag)
struct tty *tp;
caddr_t data;
{
	register struct sl_softc *sc = (struct sl_softc *)tp->T_LINEP;

	/*
	 * This is done this way, because we want these atributes to
	 * be present AFTER the user program closes the line.
	 */

	if (cmd == TIOCGETD){
		*(int *)data = (int)sc->sc_if.if_unit;
		tp->t_state &= ~TS_HUPCLS;
		tp->t_flags |= NOHANG;
		sc->sc_ttyspeed = tp->t_ispeed;
		return 0;
	}
	return EINVAL;
}
sloutput(ifp, m, dst)
register struct ifnet *ifp;
register struct mbuf *m;
struct sockaddr *dst;
{
	int s, looutput();
	extern struct ifnet loif;

	if (dst->sa_family != AF_INET) {
		printf("sl%d: af%d not supported\n", ifp->if_unit,
			dst->sa_family);
		m_freem(m);
		return EAFNOSUPPORT;
	}
#ifdef doesnt_work
	/* if it's for me, use the loopback driver */
	if (bcmp(dst->sa_data, ifp->if_addr.sa_data, 14) == 0)
		return looutput(&loif, m, dst);
#endif

	s = splimp();
	if (IF_QFULL(&ifp->if_snd)) {
		IF_DROP(&ifp->if_snd);
		m_freem(m);
		splx(s);
		sl_softc[ifp->if_unit].sc_if.if_collisions++;
		return ENOBUFS;
	}
	IF_ENQUEUE(&ifp->if_snd, m);
	if (sl_softc[ifp->if_unit].sc_oactive == 0)
		return slstart(ifp->if_unit, s); /* slstart does an splx(s) */

	splx(s);
	return 0;
}

/*
 * Start output on interface.  Get another datagram
 * to send from the interface queue and map it to
 * the interface before starting output.
 */
slstart(n, s)
int n, s;
{
	register struct sl_softc *sc = &sl_softc[n];
	register struct tty *tp;
	struct mbuf *m, *mp;

	IF_DEQUEUE(&sc->sc_if.if_snd, m);
	splx(s);
	if (m == 0)
		return 0;
	tp = sc->sc_ttyp;
	if (tp == NULL){
		printf("sl: sc_ttyp is 0\n");
		m_freem(m);
		return EHOSTUNREACH;
	}
	sc->sc_oactive = 1;

	for (mp = m; mp; mp = mp->m_next) {
		register unsigned len = mp->m_len;
		register u_char *mcp;
		u_char c;

		mcp = mtod(mp, u_char *);
		while (len--){
			c = *mcp++;
			if( c == FRAME_ESCAPE || c == FRAME_END) {
				if (putc(FRAME_ESCAPE, &tp->t_outq))
					goto full;
				c = c == FRAME_ESCAPE ?
					TRANS_FRAME_ESCAPE : TRANS_FRAME_END;
			}
			if (putc(c, &tp->t_outq))
				goto full;
		}
	}

	if (putc(FRAME_END, &tp->t_outq)){
		/*
		 * if you get many oerrors (more than 1 or two a day)
		 * you probably do not have enough clists and you should 
		 * increase "nclist" in param.c
		 */
full:
		m_freem(m);
		(void) unputc(&tp->t_outq);	/* make some space */
		putc(FRAME_END, &tp->t_outq);	/* end the packet */
		sc->sc_if.if_oerrors++;
		sc->sc_oactive = 0;
		ttstart(tp);
		return ENOBUFS;
	}
	m_freem(m);
	ttstart(tp);
	sc->sc_oactive = 0;
	sc->sc_if.if_opackets++;
	return 0;
}

/*
 * tty interface receiver interrupt.
 */
slinput(c, tp)
register c;
register struct tty *tp;
{
	register struct sl_softc *sc;
	struct mbuf *m;
	register struct ifqueue *inq;
	int s;

	sc = (struct sl_softc *)tp->T_LINEP;
	if (sc == NULL){
		printf("T_LINEP NULL\n");
		return;
	}
	c &= 0xff;
	if (sc->sc_escaped) {
		sc->sc_escaped = 0;
		switch(c) {
		case TRANS_FRAME_ESCAPE:
			c = FRAME_ESCAPE;
			break;
		case TRANS_FRAME_END:
			c = FRAME_END;
			break;
		default:
			sc->sc_if.if_ierrors++;
			return;
		}
	} else {
		switch(c) {
		case FRAME_END:
			if (sc->sc_mt == 0) {
				sc->sc_if.if_ierrors++;
				return;
			}
			sc->sc_if.if_ipackets++;
			sc->sc_mt->m_len -= sc->sc_len;
			schednetisr(NETISR_IP);
			inq = &ipintrq;

			s = splimp();
			if (IF_QFULL(inq)) {
				IF_DROP(inq);
				sc->sc_if.if_ierrors++;
				m_freem(sc->sc_m);
			} else
				IF_ENQUEUE(inq, sc->sc_m);
			splx(s);
			sc->sc_mt = 0;
			sc->sc_len = 0;
			return;
		case FRAME_ESCAPE:
			sc->sc_escaped = 1;
			return;
		}
	}
	if (sc->sc_len <= 0) {	/* have to get more buffer space */
		register struct mbuf *mm;

		MGET(mm, M_DONTWAIT, MT_DATA);
		if (mm == 0) {
			m_freem(sc->sc_m);
			sc->sc_mt = 0;
			sc->sc_len = 0;
			sc->sc_if.if_collisions++;
			return;
		}
		if (sc->sc_mt == 0){
			sc->sc_mt = sc->sc_m = mm;
		} else {
			sc->sc_mt->m_next = mm;
			sc->sc_mt = mm;
		}
		sc->sc_len = mm->m_len = MLEN;
		sc->sc_mp = mtod(mm, u_char *);
	}

	*sc->sc_mp++ = c;
	sc->sc_len--;
}

/*
 * Process an ioctl request.
 */
slioctl(ifp, cmd, data)
register struct ifnet *ifp;
int cmd;
caddr_t data;
{
	struct ifreq *ifr = (struct ifreq *)data;
	struct tty *tp;
	struct sockaddr_in *sin;
	struct sl_softc *sc;
	struct rtentry route;
#ifdef sun
	struct sockaddr_in SIN;
#endif sun
	int s = splimp(), error = 0;

#ifdef vax
# include "dh.h"
# if NDH > 0
	int dhstart();
# endif NDH
# include "dz.h"
# if NDZ > 0
	int dzstart();
# endif NDZ
# include "dmf.h"
# if NDMF > 0
	int dmfstart();
# endif NDMF
#endif vax

#ifdef sun
# include "zs.h"
# if NZS > 0
	int zsstart();
# endif  NZS
#endif sun

	switch (cmd) {
	case SIOCSIFADDR:
		if (ifp->if_flags & IFF_RUNNING)
			if_rtinit(ifp, -1);	/* delete previous route */
#ifdef sun
		ifp->if_addr = *(struct sockaddr *)data;
#else vax
		sin = (struct sockaddr_in *)&ifr->ifr_addr;
		ifp->if_addr = *(struct sockaddr *)sin;
#endif vax
		sin = (struct sockaddr_in *)&ifp->if_dstaddr;
		ifp->if_net = in_netof(sin->sin_addr);
		ifp->if_flags |= IFF_UP | IFF_RUNNING;
		/* set up routing table entry */
		if ((ifp->if_flags & IFF_ROUTE) == 0) {
			rtinit(&ifp->if_dstaddr, &ifp->if_addr, RTF_HOST|RTF_UP);
			ifp->if_flags |= IFF_ROUTE;
		}
		/* this really belongs elsewhere, but we don't want it reset
		 * when the file descriptor is closed
		 */
		sc = &sl_softc[ifp->if_unit];
		tp = sc->sc_ttyp;
		tp->t_line = SLIPDISC;
		tp->t_flags = RAW|EVENP|ODDP;
		tp->t_ispeed = tp->t_ospeed = sc->sc_ttyspeed;

		/* Unfortunately, the tty driver does not have any
		 * way of jumping directly to the correct param routine
		 * so, to get the line set to the correct baudrate
		 * we are forced to use the following kludge
		 * (Fortunately, it is only called once per line)
		 */
#ifdef vax
# if NDH > 0
		if (tp->t_oproc == dhstart)
			dhparam(minor(tp->t_dev));
		else
# endif NDH
# if NDZ > 0
		if (tp->t_oproc == dzstart)
			dzparam(minor(tp->t_dev));
		else
# endif NDZ
# if NDMF > 0
		if (tp->t_oproc == dmfstart)
			dmfparam(minor(tp->t_dev));
		else
# endif NDMF
#endif vax

#ifdef sun
# if NZS > 0
		if (tp->t_oproc == zsstart)
			zsparam(minor(tp->t_dev));
		else
# endif NZS
#endif sun
		{
			printf("Serial line attach: Unknown device\n");
			error = ENODEV;
		}
		break;

	case SIOCSIFDSTADDR:
#ifdef sun
		/* This is horrible, but they leave me little choice */
		bzero((caddr_t)&SIN, sizeof(struct sockaddr_in));
		SIN.sin_addr.s_addr = (u_long)data;
		SIN.sin_family = AF_INET; /* so much for other families... */
		sin = &SIN;
		ifp->if_dstaddr = *(struct sockaddr *)sin;
#else vax
		ifp->if_dstaddr = ifr->ifr_dstaddr;
#endif vax
		break;
#ifdef SIOCIFDETACH
	case SIOCIFDETACH:
		bzero((caddr_t)&route, sizeof (route));
		route.rt_dst = ifp->if_dstaddr;
		route.rt_gateway = ifp->if_addr;
		route.rt_flags = RTF_HOST | RTF_UP;
		(void) rtrequest(SIOCDELRT, &route);
		if_detach(ifp);
		sc = &sl_softc[ifp->if_unit];
		tp = sc->sc_ttyp;
		tp->T_LINEP = 0;
		sc->sc_ttyp = 0;
		ttyclose(tp);
		break;

#endif SIOCIFDETACH
	default:
		error = EINVAL;
	}
	splx(s);
	return error;
}
#endif NSL
ax
		ifp->if_dstaddr = ifr->ifr_dstaddr;
#endif vax
		brsys/net/                                                                                               775     540       2            0  3372246762   5414                                                                                                                                                                                                                                                                                                                                                                      sys/net/route.c                                                                                        444     540       2        16753  3360546100   7015                                                                                                                                                                                                                                                                                                                                                                      /*	route.c	6.3	83/12/15	*/

#include "../h/param.h"
#include "../h/systm.h"
#include "../h/mbuf.h"
#include "../h/protosw.h"
#include "../h/socket.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/ioctl.h"
#include "../h/errno.h"

#include "../net/if.h"
#include "../net/af.h"
#include "../net/route.h"

int	rttrash;		/* routes not in table but not freed */
struct	sockaddr wildcard;	/* zero valued cookie for wildcard searches */

/*
 * Packet routing routines.
 */
rtalloc(ro)
	register struct route *ro;
{
	register struct rtentry *rt;
	register struct mbuf *m;
	register u_long hash;
	struct sockaddr *dst = &ro->ro_dst;
	int (*match)(), doinghost;
	struct afhash h;
	u_int af = dst->sa_family;
	struct rtentry *rtmin;
	struct mbuf **table;

	if (ro->ro_rt && ro->ro_rt->rt_ifp && (ro->ro_rt->rt_flags & RTF_UP))
		return;				 /* XXX */
	if (af >= AF_MAX)
		return;
	(*afswitch[af].af_hash)(dst, &h);
	rtmin = 0;
	match = afswitch[af].af_netmatch;
	hash = h.afh_hosthash, table = rthost, doinghost = 1;
again:
	for (m = table[hash % RTHASHSIZ]; m; m = m->m_next) {
		rt = mtod(m, struct rtentry *);
		if (rt->rt_hash != hash)
			continue;
		if ((rt->rt_flags & RTF_UP) == 0 ||
		    (rt->rt_ifp->if_flags & IFF_UP) == 0)
			continue;
		if (doinghost) {
			if (bcmp((caddr_t)&rt->rt_dst, (caddr_t)dst,
			    sizeof (*dst)))
				continue;
		} else {
			if (rt->rt_dst.sa_family != af ||
			    !(*match)(&rt->rt_dst, dst))
				continue;
		}
		if (rtmin == 0 || rt->rt_use < rtmin->rt_use)
			rtmin = rt;
	}
	if (rtmin == 0 && doinghost) {
		doinghost = 0;
		hash = h.afh_nethash, table = rtnet;
		goto again;
	}
	/*
	 * Check for wildcard gateway, by convention network 0.
	 */
	if (rtmin == 0 && dst != &wildcard) {
		dst = &wildcard, hash = 0;
		goto again;
	}
	ro->ro_rt = rtmin;
	if (rtmin == 0) {
		rtstat.rts_unreach++;
		return;
	}
	rtmin->rt_refcnt++;
	if (dst == &wildcard)
		rtstat.rts_wildcard++;
}

rtfree(rt)
	register struct rtentry *rt;
{

	if (rt == 0)
		panic("rtfree");
	rt->rt_refcnt--;
	if (rt->rt_refcnt == 0 && (rt->rt_flags&RTF_UP) == 0) {
		rttrash--;
		(void) m_free(dtom(rt));
	}
}

/*
 * Force a routing table entry to the specified
 * destination to go through the given gateway.
 * Normally called as a result of a routing redirect
 * message from the network layer.
 *
 * N.B.: must be called at splnet or higher
 *
 * Should notify all parties with a reference to
 * the route that it's changed (so, for instance,
 * current round trip time estimates could be flushed),
 * but we have no back pointers at the moment.
 */
rtredirect(dst, gateway, flags)
	struct sockaddr *dst, *gateway;
	int flags;
{
	struct route ro;
	register struct rtentry *rt;

	/* verify the gateway is directly reachable */
	if (if_ifwithnet(gateway) == 0) {
		rtstat.rts_badredirect++;
		return;
	}
	ro.ro_dst = *dst;
	ro.ro_rt = 0;
	rtalloc(&ro);
	rt = ro.ro_rt;
	/*
	 * Create a new entry if we just got back a wildcard entry
	 * or the the lookup failed.  This is necessary for hosts
	 * which use routing redirects generated by smart gateways
	 * to dynamically build the routing tables.
	 */
	if (rt &&
	    (*afswitch[dst->sa_family].af_netmatch)(&wildcard, &rt->rt_dst)) {
		rtfree(rt);
		rt = 0;
	}
	if (rt == 0) {
		rtinit(dst, gateway, RTF_GATEWAY);
		rtstat.rts_dynamic++;
		return;
	}
	/*
	 * Don't listen to the redirect if it's
	 * for a route to an interface. 
	 */
	if (rt->rt_flags & RTF_GATEWAY) {
		if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
			/*
			 * Changing from route to gateway => route to host.
			 * Create new route, rather than smashing route to net.
			 */
			rtfree(rt);
			rtinit(dst, gateway, flags);
			rtstat.rts_newgateway++;
		} else {
			/*
			 * Smash the current notion of the gateway to
			 * this destination.  This is probably not right,
			 * as it's conceivable a flurry of redirects could
			 * cause the gateway value to fluctuate wildly during
			 * dynamic routing reconfiguration.
			 */
			rt->rt_gateway = *gateway;
			rtfree(rt);
			rtstat.rts_newgateway++;
		}
	}
}

/*
 * Routing table ioctl interface.
 */
rtioctl(cmd, data)
	int cmd;
	caddr_t data;
{

	if (cmd != SIOCADDRT && cmd != SIOCDELRT)
		return (EINVAL);
	if (!suser())
		return (u.u_error);
	return (rtrequest(cmd, (struct rtentry *)data));
}

/*
 * Carry out a request to change the routing table.  Called by
 * interfaces at boot time to make their ``local routes'' known,
 * for ioctl's, and as the result of routing redirects.
 */
rtrequest(req, entry)
	int req;
	register struct rtentry *entry;
{
	register struct mbuf *m, **mprev;
	register struct rtentry *rt;
	struct afhash h;
	int s, error = 0, (*match)();
	u_int af;
	u_long hash;
	struct ifnet *ifp;

	af = entry->rt_dst.sa_family;
	if (af >= AF_MAX)
		return (EAFNOSUPPORT);
	(*afswitch[af].af_hash)(&entry->rt_dst, &h);
	if (entry->rt_flags & RTF_HOST) {
		hash = h.afh_hosthash;
		mprev = &rthost[hash % RTHASHSIZ];
	} else {
		hash = h.afh_nethash;
		mprev = &rtnet[hash % RTHASHSIZ];
	}
	match = afswitch[af].af_netmatch;
	s = splimp();
	for (; m = *mprev; mprev = &m->m_next) {
		rt = mtod(m, struct rtentry *);
		if (rt->rt_hash != hash)
			continue;
		if (entry->rt_flags & RTF_HOST) {
#define	equal(a1, a2) \
	(bcmp((caddr_t)(a1), (caddr_t)(a2), sizeof (struct sockaddr)) == 0)
			if (!equal(&rt->rt_dst, &entry->rt_dst))
				continue;
		} else {
			if (rt->rt_dst.sa_family != entry->rt_dst.sa_family ||
			    (*match)(&rt->rt_dst, &entry->rt_dst) == 0)
				continue;
		}
		if (equal(&rt->rt_gateway, &entry->rt_gateway))
			break;
	}
	switch (req) {

	case SIOCDELRT:
		if (m == 0) {
			error = ESRCH;
			goto bad;
		}
		*mprev = m->m_next;
		if (rt->rt_refcnt > 0) {
			rt->rt_flags &= ~RTF_UP;
			rttrash++;
			m->m_next = 0;
		} else
			(void) m_free(m);
		break;

	case SIOCADDRT:
		if (m) {
			error = EEXIST;
			goto bad;
		}
		for (ifp = ifnet; ifp; ifp = ifp->if_next) {
			if (ifp->if_addr.sa_family != entry->rt_dst.sa_family ||
				!(ifp->if_flags&IFF_UP))
					continue;
			if ((ifp->if_flags & IFF_POINTOPOINT) &&
			    (bcmp(ifp->if_dstaddr.sa_data, entry->rt_dst.sa_data, 14) == 0)
			    || (bcmp(ifp->if_dstaddr.sa_data, entry->rt_gateway.sa_data, 14) == 0))
				break;
		}
		if (ifp == 0) {
			ifp = if_ifwithaddr(&entry->rt_gateway);
			if (ifp == 0) {
				ifp = if_ifwithnet(&entry->rt_gateway);
				if (ifp == 0) {
					error = ENETUNREACH;
					goto bad;
				}
			}
		}
		m = m_get(M_DONTWAIT, MT_RTABLE);
		if (m == 0) {
			error = ENOBUFS;
			goto bad;
		}
		*mprev = m;
		m->m_off = MMINOFF;
		m->m_len = sizeof (struct rtentry);
		rt = mtod(m, struct rtentry *);
		rt->rt_hash = hash;
		rt->rt_dst = entry->rt_dst;
		rt->rt_gateway = entry->rt_gateway;
		rt->rt_flags =
		    RTF_UP | (entry->rt_flags & (RTF_HOST|RTF_GATEWAY));
		rt->rt_refcnt = 0;
		rt->rt_use = 0;
		rt->rt_ifp = ifp;
		break;
	}
bad:
	splx(s);
	return (error);
}

/*
 * Set up a routing table entry, normally
 * for an interface.
 */
rtinit(dst, gateway, flags)
	struct sockaddr *dst, *gateway;
	int flags;
{
	struct rtentry route;
	int cmd;

	if (flags == -1) {
		cmd = (int)SIOCDELRT;
		flags = 0;
	} else {
		cmd = (int)SIOCADDRT;
	}
	bzero((caddr_t)&route, sizeof (route));
	route.rt_dst = *dst;
	route.rt_gateway = *gateway;
	route.rt_flags = flags;
	(void) rtrequest(cmd, &route);
}

/*
 * Detach an interface from the
 * list of "active" interfaces.
 */
if_detach(ifp)
	struct ifnet *ifp;
{
	register struct ifnet *p = ifnet;
	int s = splimp();	

	if (p == ifp)
		ifnet = p->if_next;
	else
		while (p)
			if (p->if_next == ifp) {
				p->if_next = ifp->if_next;
				break;
			} else
				p = p->if_next;
	splx(s);
	return;
}
(int)SIOCADDRT;
	}
	bsys/sys/                                                                                               775     540       2            0  3372247272   5441                                                                                                                                                                                                                                                                                                                                                                      sys/sys/tty_conf.c.sun                                                                                 444     540       2         4522  3372247244  10321                                                                                                                                                                                                                                                                                                                                                                      /*	@(#)tty_conf.c 1.4 84/01/03 SMI; from UCB 4.3 83/05/27	*/

#include "../h/param.h"
#include "../h/systm.h"
#include "../h/buf.h"
#include "../h/tty.h"
#include "../h/conf.h"

int	nodev();
int	nulldev();

int	ttyopen(),ttyclose(),ttread(),ttwrite(),nullioctl(),ttstart();
int	ttyinput();

#include "bk.h"
#if NBK > 0
int	bkopen(),bkclose(),bkread(),bkinput(),bkioctl();
#endif

#include "tb.h"
#if NTB > 0
int	tbopen(),tbclose(),tbread(),tbinput(),tbioctl();
#endif

#include "ms.h"
#if NMS > 0
int	msopen(), msclose(), msread(), msioctl(), msinput();
#endif

#include "kb.h"
#if NKB > 0
int	kbdopen(), kbdclose(), kbdioctl(), kbdinput();
#endif

#include "sl.h"
#if NSL > 0
int	slopen(), slinput(), sltioctl();
#endif

struct	linesw linesw[] =
{
	ttyopen, nodev, ttread, ttwrite, nullioctl,
	ttyinput, nodev, nulldev, ttstart, nulldev,
#if NBK > 0
	bkopen, bkclose, bkread, ttwrite, bkioctl,
	bkinput, nodev, nulldev, ttstart, nulldev,
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
	ttyopen, ttyclose, ttread, ttwrite, nullioctl,
	ttyinput, nodev, nulldev, ttstart, nulldev,
#if NTB > 0
	tbopen, tbclose, tbread, nodev, tbioctl,
	tbinput, nodev, nulldev, ttstart, nulldev,		/* 3 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
#if NTB > 0
	tbopen, tbclose, tbread, nodev, tbioctl,
	tbinput, nodev, nulldev, ttstart, nulldev,		/* 4 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
#if NMS > 0
	msopen, msclose, msread, nodev, msioctl,
	msinput, nodev, nulldev, nulldev, nulldev,		/* 5 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
#if NKB > 0
	kbdopen, kbdclose, ttread, ttwrite, kbdioctl,
	kbdinput, nodev, nulldev, ttstart, nulldev,		/* 6 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
#if NSL > 0
	slopen, nulldev, nodev, nodev, sltioctl,
	slinput, nodev, nulldev, ttstart, nulldev,		/* 7 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
};

int	nldisp = sizeof (linesw) / sizeof (linesw[0]);

/*
 * Do nothing specific version of line
 * discipline specific ioctl command.
 */
/*ARGSUSED*/
nullioctl(tp, cmd, data, flags)
	struct tty *tp;
	char *data;
	int flags;
{

#ifdef lint
	tp = tp; data = data; flags = flags;
#endif
	return (-1);
}
v, nodev,
#endif
#if NSL > 0
	slopen, nulldev, nodev, nodev, sltioctl,
	slinput, nodev, nulldev, ttstart, nulldev,		/* 7 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, sys/sys/tty_conf.c.vax                                                                                 444     540       2         3373  3354412451  10307                                                                                                                                                                                                                                                                                                                                                                      /*	tty_conf.c	6.2	83/09/25	*/

#include "../h/param.h"
#include "../h/systm.h"
#include "../h/buf.h"
#include "../h/tty.h"
#include "../h/conf.h"

int	nodev();
int	nulldev();

int	ttyopen(),ttyclose(),ttread(),ttwrite(),nullioctl(),ttstart();
int	ttyinput();

#include "bk.h"
#if NBK > 0
int	bkopen(),bkclose(),bkread(),bkinput(),bkioctl();
#endif

#include "tb.h"
#if NTB > 0
int	tbopen(),tbclose(),tbread(),tbinput(),tbioctl();
#endif

#include "sl.h"
#if NSL > 0
int	slopen(), slinput(), sltioctl();
#endif

struct	linesw linesw[] =
{
	ttyopen, nulldev, ttread, ttwrite, nullioctl,
	ttyinput, nodev, nulldev, ttstart, nulldev,
#if NBK > 0
	bkopen, bkclose, bkread, ttwrite, bkioctl,
	bkinput, nodev, nulldev, ttstart, nulldev,
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
	ttyopen, ttyclose, ttread, ttwrite, nullioctl,
	ttyinput, nodev, nulldev, ttstart, nulldev,
#if NTB > 0
	tbopen, tbclose, tbread, nodev, tbioctl,
	tbinput, nodev, nulldev, ttstart, nulldev,		/* 3 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
#if NTB > 0
	tbopen, tbclose, tbread, nodev, tbioctl,
	tbinput, nodev, nulldev, ttstart, nulldev,		/* 4 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
#if NSL > 0
	slopen, nulldev, nodev, nodev, sltioctl,
	slinput, nodev, nulldev, ttstart, nulldev,		/* 5 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
};

int	nldisp = sizeof (linesw) / sizeof (linesw[0]);

/*
 * Do nothing specific version of line
 * discipline specific ioctl command.
 */
/*ARGSUSED*/
nullioctl(tp, cmd, data, flags)
	struct tty *tp;
	char *data;
	int flags;
{

#ifdef lint
	tp = tp; data = data; flags = flags;
#endif
	return (-1);
}
v, nodev,
#endif
#if NSL > 0
	slopen, nulldev, nodev, nodev, sltioctl,
	slinput, nodev, nulldev, ttstart, nulldev,		/* 5 */
#else
	nodev, nodev, nodev, nodev, nodev,
	nodev, nodev, nodev, nodev, nodev,
#endif
};

int	nldisp = sizeof (linesw) / sizeof (linesw[0]                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                uct rtentry *rt;
	struct afhash h;
	int s, error = 0, (*match)();
	u_int af;
	u_long hash;
	struct ifnet *ifp;

	af = entry->rt_dst.sa_family;
	if (af >= AF_MAX)
		return (EAFNOSUPPORT);
	(*afswitch[af].af_hash)(&entry->rt_dst, &h);
	if (entry->rt_flags & RTF_HOST) {
		hash = h.afh_hosthash;
		mprev = &rthost[hash % RTHASHSIZ];
	} else {
		hash = h.afh_nethash;
		mprev = &rtnet[hash % RTHASHSIZ];
	}
	match = afswitch[af].af_netmatch;
	s = splimp();
	for (; m = *mprev; mprev = &m->m_next) {
		rt = mtod(m, struct rtentry *);
		if (rt->rt_hash != hash)
			continue;
		if (entry->rt_flags & RTF_HOST) {
#define	equal(a1, a2) \
	(bcmp((caddr_t)(a1), (caddr_t)(a2), sizeof (struct sockaddr)) == 0)
			if (!equal(&rt->rt_dst, &entry->rt_dst))
				continue;
		} else {
			if (rt->rt_dst.sa_family != entry->rt_dst.sa_family ||
			    (*match)(&rt->rt_dst, &entry->rt_dst) == 0)
				continue;
		}
		if (equal(&rt->rt_gateway, &entry->rt_gateway))
			break;
	}
	switch (req) {

	case SIOCDELRT:
		if (m == 0) {
			error = ESRCH;
			goto bad;
		}
		*mprev = m->m_next;
		if (rt->rt_refcnt > 0) {
			rt->rt_flags &= ~RTF_UP;
			rttrash++;
			m->m_next = 0;
		} else
			(void) m_free(m);
		break;

	case SIOCADDRT:
		if (m) {
			error = EEXIST;
			goto bad;
		}
		for (ifp = ifnet; ifp; ifp = ifp->if_next) {
			if (ifp->if_addr.sa_family != entry->rt_dst.sa_family ||
				!(ifp->if_flags&IFF_UP))
					continue;
			if ((ifp->if_flags & IFF_POINTOPOINT) &&
			    (bcmp(ifp->if_dstaddr.sa_data, entry->rt_dst.sa_data, 14) == 0)
			    || (bcmp(ifp->if_dstaddr.sa_data, entry->rt_gateway.sa_data, 14) == 0))
				break;
		}
		if (ifp == 0) {
			ifp = if_ifwithaddr(&entry->rt_gateway);
			if (ifp == 0) {
				ifp = if_ifwithnet(&entry->rt_gateway);
				if (ifp == 0) {
					error = ENETUNREACH;
					goto bad;
				}
			}
		}
		m = m_get(M_DONTWAIT, MT_RTABLE);
		if (m == 0) {
			error = ENOBUFS;
			goto bad;
		}
		*mprev = m;
		m->m_off = MMINOFF;
		m->m_len = sizeof (struct rtentry);
		rt = mtod(m, struct rtentry *);
		rt->rt_hash = hash;
		rt->rt_dst 