#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# This archive created: Fri Jul  5 10:55:11 1991

export PATH; PATH=/bin:/usr/bin:$PATH
#	slip-4.1/README
#	slip-4.1/slip-attach.c
#	slip-4.1/slip.h
#	slip-4.1/slipencode.c
#	slip-4.1/streamsip.c
if test -f 'slip-4.1/README'
then
	echo shar: "will not over-write existing file 'slip-4.1/README'"
else
if test ! -d 'slip-4.1'
	mkdir 'slip-4.1'
fi
sed -e s/X// << \SHAR_EOF > 'slip-4.1/README'
XREADME for slip-4.1
X
XWorks for SunOS 4.1.1 20/12/1990
XAdded congestion control 24/06/1991
X
Xcp slip.h /usr/include/sys
Xcp slip.h /sys/sys
Xcp streamsip.c slipencode.c /sys/os
X
Xedit /sys/conf.common/files.cmn
X
Xos/streamsip.c                optional slip
Xos/slipencode.c               optional slip
X
X
Xedit /sys/sun/str_conf.c
X
X#include "slip.h"
X
X#if     NSLIP > 0
Xextern  struct  streamtab slipencode;
Xextern  struct  streamtab streams_ip;
X#endi
X
X#if     NSLIP > 0
X	{ "slipen", &slipencode },
X	{ "str_ip", &streams_ip },
X#endif
X
X/sys/sun?/conf/MACHINE
X
Xpseudo-device    slip2
X
XBuild the new kernel, install and reboot.
X
Xcompile slip-attach
X
Xrun slip-attach
X	slip-attach device speed local remote netmask
Xe.g.
X/usr/local/etc/slip-attach /dev/ttya 9600 192.42.62.1 192.42.62.2 255.255.255.0
X
XIf you wish to user this under 4.0 you will nedd to add the following
Xdeclacation "char    mclrefcnt[];" to streamsip.c.
X--
XMark Andrews, CSIRO Div Maths & Stats, PO Box 218, Lindfield, NSW, Australia.
XPHONE:  +61 2 413 7058          ACSNET: marka@dmssyd.dms.oz
XARPA: marka@syd.dms.csiro.au    UUCP: ....!uunet!syd.dms.csiro.au!marka
SHAR_EOF
fi
if test -f 'slip-4.1/slip-attach.c'
then
	echo shar: "will not over-write existing file 'slip-4.1/slip-attach.c'"
else
if test ! -d 'slip-4.1'
	mkdir 'slip-4.1'
fi
sed -e s/X// << \SHAR_EOF > 'slip-4.1/slip-attach.c'
X/*
X *	slip-attach.c
X *
X *	Slip-attach opens and initalises the named device at the
X *	requested speed, attaches the slip streams encodeing module and 
X *	and streams IP network module and initaliases them. 
X *
X *	Copyright CSIRO Division of Mathematics and Statistics 21 June 1990
X *
X *	Portions of this code may be held by, Doug Kingston,Rayan Zachariassen,
X *	and Greg Earle (see below).
X *
X *	Permission is hereby granted for this code to be distributed
X *	free of charge with this copyright intact and does not interfere
X *	with any copyrights held by the above. Derived works should
X *	be marked as so.
X */
X
X/*
X * sliplogin.c
X *
X * This program initializes its own tty port to be an async TCP/IP interface.
X * It merely sets up the SLIP module all by its lonesome on the STREAMS stack,
X * initializes the network interface, and pauses forever waiting for hangup.
X *
X * It is a remote descendant of several similar programs with incestuous ties:
X * - Kirk Smith's slipconf, modified by Richard Johnsson @ DEC WRL.
X * - slattach, probably by Rick Adams but touched by countless hordes.
X * - the original sliplogin for 4.2bsd, Doug Kingston the mover behind it.
X * - a simple slattach-like program used to test the STREAMS SLIP code.
X *
X * Doug Kingston 8810??		- logging + first pass at adding I_STR ioctl's
X * Rayan Zachariassen 881011	- version for SunOS STREAMS SLIP
X * Greg Earle 890331		- added tip/UUCP style LCK lock file
X */
X
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/stropts.h>
X#include <sys/termios.h>
X#include <sys/ttold.h>
X#include <sys/sockio.h>
X#include <sys/file.h>
X#include <sys/syslog.h>
X
X#include <sys/slip.h>
X
X#include <netinet/in.h>
X#include <net/if.h>
X
X#include <stdio.h>
X#include <errno.h>
X#include <ctype.h>
X#include <netdb.h>
X
X#include <signal.h>
X#include <strings.h>
X#include <pwd.h>
X#ifdef BSD >= 43
X#include <ttyent.h>
X#endif
X
Xvoid exit();
X
Xmain(argc, argv)
X	int argc;
X	char *argv[];
X{
X	int		fd, s, unit;
X	int speed,i;
X	int		sfd = 0;
X	char	*device;
X	char	*netmask;
X	char	*localaddr;
X	char	*dstaddr;
X	struct termios	tios;
X	struct ifreq	ifr;
X	extern void	findid();
X
X	if (getuid() == 0) {
X		if (argc != 6) {
X			(void) fprintf(stderr,
X				       "Usage: %s device speed localaddr destaddr netmask\n", argv[0]);
X			exit(1);
X		}
X		device = argv[1];
X		speed = atoi(argv[2]);
X		localaddr = argv[3];
X		dstaddr = argv[4];
X		netmask = argv[5];
X	} else
X		exit(1);
X
X	switch (speed){
X	case 50: speed = B50; break;
X	case 75: speed = B75; break;
X	case 110: speed = B110; break;
X	case 134: speed = B134; break;
X	case 150: speed = B150; break;
X	case 200: speed = B200; break;
X	case 300: speed = B300; break;
X	case 600: speed = B600; break;
X	case 1200: speed = B1200; break;
X	case 1800: speed = B1800; break;
X	case 2400: speed = B2400; break;
X	case 4800: speed = B4800; break;
X	case 9600: speed = B9600; break;
X	case 19200: speed = B19200; break;
X	case 38400: speed = B38400; break;
X	default:
X		(void)fprintf(stderr,"bad speed %d\n",speed);
X		exit(1);
X	}
X
X	for ( i = getdtablesize(); i--; )
X		(void)close(i);
X
X	switch (fork()) {
X	case	0:	/* child */
X		break;
X	default:
X		exit(0);
X		/* NOTREACHED */
X	case	-1:	/* error */
X		i = errno;
X		openlog("slip-attach", LOG_PID|LOG_CONS, LOG_DAEMON);
X		errno = i;
X		syslog(LOG_ERR," fork() %m\n");
X		exit(i);
X		/* NOTREACHED */
X	}
X
X	openlog("slip-attach", LOG_PID|LOG_CONS, LOG_DAEMON);
X
X	if ((fd = open("/dev/tty", O_RDONLY, 0)) >= 0) {
X		(void) ioctl(fd, TIOCNOTTY, 0);
X		(void) close(fd);
X	}
X
X
X	if (( sfd = open(device,O_RDWR,0)) < 0 ) {
X		syslog(LOG_ERR, "open: %s: %m",device);
X		exit(1);
X	}
X
X	(void) fchmod(sfd, 0600);
X
X	/* pop all streams modules */
X	while (ioctl(sfd, I_POP, 0) == 0)
X		continue;
X
X	/* set up the line parameters */
X	if (ioctl(sfd, TCGETS, (caddr_t)&tios) < 0) {
X		syslog(LOG_ERR, "ioctl (TCGETS): %m");
X		exit(1);
X	}
X	tios.c_cflag = CS8|CREAD|HUPCL|speed;
X	tios.c_iflag = IGNBRK;
X
X	if (ioctl(sfd, TCSETS, (caddr_t)&tios) < 0) {
X		syslog(LOG_ERR, "ioctl (TCSETS): %m");
X		exit(1);
X	}
X
X	/* push the SLIP module */
X	if (ioctl(sfd, I_PUSH, "slipen") < 0) {
X		syslog(LOG_ERR, "ioctl (I_PUSH) slipen: %m");
X		exit(1);
X	}
X	if (ioctl(sfd, I_PUSH, "str_ip") < 0) {
X		syslog(LOG_ERR, "ioctl (I_PUSH) str_ip: %m");
X		exit(1);
X	}
X
X	/* find out what unit number we were assigned */
X	if (ioctl(sfd, SLIOGUNIT, (caddr_t)&unit) < 0) {
X		syslog(LOG_ERR, "ioctl (SLIOGUNIT): %m");
X		exit(1);
X	}
X
X	syslog(LOG_NOTICE, "attaching stream%d: local %s remote %s mask %s\n",
X		unit, localaddr, dstaddr, netmask);
X
X	/* set the local and remote interface addresses */
X	s = socket(AF_INET, SOCK_DGRAM, 0);
X
X	(void) sprintf(ifr.ifr_name, "%s%d", "stream", unit);
X	in_getaddr(netmask, &ifr.ifr_addr);
X	if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) {
X		syslog(LOG_ERR, "ioctl (SIOCSIFNETMASK): %m");
X		exit(1);
X	}
X
X	(void) sprintf(ifr.ifr_name, "%s%d", "stream", unit);
X	in_getaddr(dstaddr, &ifr.ifr_addr);
X	if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
X		syslog(LOG_ERR, "ioctl (SIOCSIFDSTADDR): %m");
X		exit(1);
X	}
X
X	(void) sprintf(ifr.ifr_name, "%s%d", "stream", unit);
X	in_getaddr(localaddr, &ifr.ifr_addr);
X	/* this has the side-effect of marking the interface up */
X	if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
X		syslog(LOG_ERR, "ioctl (SIOCSIFADDR): %m");
X		exit(1);
X	}
X	(void)pause();
X	exit(0);
X	/*NOTREACHED*/
X}
X
X
Xin_getaddr(s, saddr)
X	char *s;
X	struct sockaddr *saddr;
X{
X	register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
X	struct hostent *hp;
X	struct netent *np;
X	u_long val;
X	extern struct in_addr inet_makeaddr();
X	extern u_long inet_addr();
X 
X	bzero((caddr_t)saddr, sizeof *saddr);
X	sin->sin_family = AF_INET;
X	val = inet_addr(s);
X	if (val != (u_long)-1) {
X		sin->sin_addr.s_addr = val;
X		return;
X	}
X	hp = gethostbyname(s);
X	if (hp) {
X		sin->sin_family = hp->h_addrtype;
X		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
X		return;
X	}
X	np = getnetbyname(s);
X	if (np) {
X		sin->sin_family = np->n_addrtype;
X		sin->sin_addr = inet_makeaddr((int)np->n_net, (int)INADDR_ANY);
X		return;
X	}
X	(void) fprintf(stderr, "slip_attach: %s: bad value\n", s);
X	syslog(LOG_ERR, "%s: bad value\n", s);
X	exit(1);
X	/* NOTREACHED */
X}
SHAR_EOF
fi
if test -f 'slip-4.1/slip.h'
then
	echo shar: "will not over-write existing file 'slip-4.1/slip.h'"
else
if test ! -d 'slip-4.1'
	mkdir 'slip-4.1'
fi
sed -e s/X// << \SHAR_EOF > 'slip-4.1/slip.h'
X/*
X * Header file for SunOS 4.0 streams SLIP module
X *
X * Copyright 1988 by Rayan Zachariassen
X *
X * You may do anything with this file except put your own
X * copyright on it or change or remove this copyright notice.
X */
X
X#ifndef	_sys_slip_h
X#define	_sys_slip_h
X
X/*
X * To compensate for lack of M_HANGUP on dialout lines, we use M_UNHANGUP
X * as symptom of a possible carrier change, and generate a signal whenever
X * an M_UNHANGUP passes by so the application can check for DCD.  This is
X * a workaround that should go away when M_HANGUP is generated on dialouts.
X */
X
X#include <sys/signal.h>
X
X/* signal to send application on stream device non-hangup DCD change */
X#define	SIGDCD		SIGUSR1
X
X
X#define	SLIPIFNAME	"slip"		/* base name of network interface */
X
X#define	SLIOGUNIT	_IOR(t, 62, int)		/* get SLIP unit no. */
X#define	SLIOGSTATS	_IOR(t, 63, struct slipstat)	/* get statistics */
X#define	SLIOSFLAGS	_IOW(t, 64, int)		/* set flags */
X
Xstruct slipstat {
X	u_int		sl_ibytes;	/* total number of data bytes in */
X	u_int		sl_ipackets;	/* total number of data packets in */
X	u_int		sl_ierrors;	/* total number of input errors */
X	u_int		sl_obytes;	/* total number of data bytes out */
X	u_int		sl_opackets;	/* total number of data packets out */
X	u_int		sl_oerrors;	/* total number of output errors */
X};
X
X/* end of what the user-level process should care about */
X
X/* See RFC1055 for the origin of the following magic numbers */
X
X#define SLIPMTU		1006	/* this is the IP-level MTU */
X
X#define	END	0300		/* a frame just finished */
X#define	ESC	0333		/* introduces an escape sequence */
X#define	ESC_END	0334		/* the data contained an END */
X#define	ESC_ESC	0335		/* the data contained an ESC */
X
X#endif	/* !_sys_slip_h */
SHAR_EOF
fi
if test -f 'slip-4.1/slipencode.c'
then
	echo shar: "will not over-write existing file 'slip-4.1/slipencode.c'"
else
if test ! -d 'slip-4.1'
	mkdir 'slip-4.1'
fi
sed -e s/X// << \SHAR_EOF > 'slip-4.1/slipencode.c'
X/*
X *	SLIP streams packet encoding/decoding module. SunOS 4.1.
X *
X *	Copyright CSIRO Division of Mathematics and Statistics 21 June 1990
X *
X *	Author: Mark Andrews, marka@syd.dms.csiro.au
X *	
X *	Tested Systems:
X *		Sun 3/50 SunOS4.1 console ports.
X *
X *	The encoding/decoding algorithim is derived from work by
X *	Rayan Zachariassen, rayan@ai.toronto.edu.
X *
X *      Permission is hereby granted for this code to be distributed
X *      free of charge with this copyright intact. Derived works should
X *      be marked as so.
X
X */
X
X#include <sys/types.h>
X#include <sys/stream.h>
X#include <sys/stropts.h>
X#include <sys/param.h>
X#include <sys/syslog.h>
X
X#include <sys/slip.h> /* from 4.0 slip code only needed for SLIPMTU */
X
X
Xtypedef struct {
X	int inlen;
X	int sawescape;
X	int overrun;
X	unsigned char *dp;
X	unsigned char buf[SLIPMTU];
X	} slipb;
X
Xstatic int encode();
Xstatic int decode();
Xstatic int slopen();
Xstatic int slclose();
Xstatic int wput();
X
Xstatic struct module_info minfo = { 517, "slipen", 0, INFPSZ, 57600, 57600};
X
Xstatic struct qinit rinit = {
X	decode, NULL, slopen, slclose, NULL, &minfo, NULL
X	};
Xstatic struct qinit winit = {
X	wput, encode, NULL, NULL, NULL, &minfo, NULL
X	};
X
Xstruct streamtab slipencode = { &rinit, &winit, NULL, NULL };
X
X
Xstatic int slopen(q,dev,flag,sflag)
X    queue_t *q;
X    dev_t dev;
X    int flag;
X    int sflag;
X{
X    slipb *b;
X    int s;
X
X    if((b = (slipb *)kmem_alloc(sizeof(slipb))) == NULL)
X	return(OPENFAIL);
X
X    b->dp = b->buf;
X    b->inlen = 0;
X    b->overrun = 0;
X    b->sawescape = 0;
X
X    s = splstr(s);
X    OTHERQ(q)->q_ptr = q->q_ptr = (char *)b;
X    splx(s);
X
X    return(0);
X}
X
Xstatic int slclose(q,flag)
X    queue_t *q;
X    int flag;
X{
X    caddr_t p = q->q_ptr;
X    int s;
X
X    s = splstr();
X    OTHERQ(q)->q_ptr = q->q_ptr = 0;
X    kmem_free(p,sizeof(slipb));
X    splx(s);
X}
X
Xstatic int wput(q,mp)
X    queue_t *q;
X    mblk_t *mp;
X{
X    switch (mp->b_datap->db_type) {
X    case M_DATA:
X    case M_FLUSH:
X	putq(q,mp);
X	break;
X    default:
X	putnext(q,mp);
X    }
X}
X
Xstatic int encode(q)
X    queue_t *q;
X{
X    mblk_t *mp, *bp, *nb;
X    int len;
X    unsigned char *rp;
X    unsigned char ch;
X
X
X    while ((mp = getq(q)) != NULL) {
X	switch (mp->b_datap->db_type) {
X	default: /* paranoid */
X	    putnext(q,mp);
X	    continue;
X	case M_FLUSH:
X	    if (*mp->b_rptr & FLUSHW)
X		flushq(q, FLUSHDATA);
X	    putnext(q,mp);
X	    continue;
X	case M_DATA:
X	    if(!canput(q->q_next)) {
X		putbq(q,mp);
X		return;
X	    }
X	    len = 2;
X	    for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
X		rp = bp->b_rptr;
X		while (rp < bp->b_wptr) {
X		    ch = *rp++;
X		    len++;
X		    if ((ch == ESC) || (ch == END))
X			len++;
X		}
X	    }
X	    if ((nb = allocb(len,BPRI_MED)) == NULL) {
X		log(LOG_DEBUG,"slipencode: unable to allocate write buffer\n");
X	       freemsg(mp);
X	       continue;
X	    }
X	    *nb->b_wptr++ = END;
X	    for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
X		rp = bp->b_rptr;
X		while (rp < bp->b_wptr) {
X		    ch = *rp++;
X		    if (ch == END) {
X			*nb->b_wptr++ = ESC;
X			*nb->b_wptr++ = ESC_END;
X		    } else if ( ch == ESC ) {
X			*nb->b_wptr++ = ESC;
X			*nb->b_wptr++ = ESC_ESC;
X		    } else
X			*nb->b_wptr++ = ch;
X		}
X	    }
X	    *nb->b_wptr++ = END;
X	    putnext(q,nb);
X	    freemsg(mp);
X	}
X    }
X}
X
Xstatic int decode(q,mp)
X    queue_t *q;
X    mblk_t *mp;
X{
X    slipb *b = (slipb *)q->q_ptr;
X    mblk_t *bp, *nb;
X    unsigned char *rp;
X    unsigned char ch;
X
X    switch (mp->b_datap->db_type) {
X    default:
X	putnext(q,mp);
X	break;
X    case M_FLUSH:
X	if (*mp->b_rptr & FLUSHR)
X	    flushq(q, FLUSHDATA);
X	putnext(q,mp);
X	break;
X    case M_DATA:
X	for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
X	    rp = bp->b_rptr;
X	    while (rp < bp->b_wptr) {
X		ch = *rp++;
X		if (b->sawescape) { /* undo escape */
X		    b->sawescape = 0;
X		    if ( ch == ESC_END )
X			ch = END;
X		    else if ( ch == ESC_ESC )
X			ch = ESC;
X		} else if (ch == END) { /* start/end character */
X		    if (b->overrun) { /* set up to recieve new packet */
X			b->overrun = 0;
X			b->inlen = 0;
X			continue;
X		    }
X		    if (b->inlen == 0) /* start flag ignore */
X			continue;
X
X		    /* build new message */
X		    if ((nb = allocb(b->inlen,BPRI_MED)) == NULL) {
X		       log(LOG_DEBUG,"slipencode: unable to allocate read buffer dropping packet\n");
X		       b->inlen = 0;
X		       b->dp = b->buf;
X		       continue;
X		    }
X		    bcopy(b->buf, nb->b_wptr, b->inlen);
X		    nb->b_wptr += b->inlen;
X		    putnext(q,nb);
X
X		    b->inlen = 0;	/* setup for next packet */
X		    b->dp = b->buf;
X		    continue;
X
X		} else if (ch == ESC) {
X		    b->sawescape = 1;
X		    continue;
X		}
X		if (++(b->inlen) > SLIPMTU) {
X		    if(!b->overrun)
X			log(LOG_ERR,"slipencode: overrun\n");
X		    b->overrun = 1;
X		    b->dp = b->buf;
X		    continue;
X		}
X		*(b->dp)++ = ch;
X	    }
X	    bp->b_rptr = rp;
X	}
X	freemsg(mp);
X    }
X}
SHAR_EOF
fi
if test -f 'slip-4.1/streamsip.c'
then
	echo shar: "will not over-write existing file 'slip-4.1/streamsip.c'"
else
if test ! -d 'slip-4.1'
	mkdir 'slip-4.1'
fi
sed -e s/X// << \SHAR_EOF > 'slip-4.1/streamsip.c'
X/*
X *	Streams IP network module. SunOS 4.1.
X *
X *	Copyright CSIRO Division of Mathematics and Statistics 21 June 1990
X *
X *	Author: Mark Andrews, marka@syd.dms.csiro.au
X *
X *	Tested Systems:
X *		Sun 3/50 SunOS4.1 console ports.
X *
X *	Permission is hereby granted for this code to be distributed
X *	free of charge with this copyright intact. Derived works should
X *	be marked as so.
X */
X
X#include "slip.h"
X#if NSLIP > 0
X#include <sys/types.h>
X#include <sys/stream.h>
X#include <sys/stropts.h>
X#include <sys/param.h>
X#include <sys/systm.h>
X#include <sys/user.h>
X#include <sys/errno.h>
X#include <sys/mbuf.h>
X#include <sys/socket.h>
X#include <sys/uio.h>
X#include <sys/ioctl.h>
X#include <sys/file.h>
X#include <net/if.h>
X#include <net/netisr.h>
X#include <netinet/in.h>
X#include <netinet/in_var.h>
X#include <sys/syslog.h>
X
X#include <sys/slip.h> /* needed for SLIPMTU (should be derived from
X	underlying streams module for PPP), and SLIOGUNIT */
X
X
Xstatic int rput();
Xstatic int wput();
Xstatic int if_in();
Xstatic int stream_open();
Xstatic int stream_close();
Xstatic int stream_ioctl();
Xstatic int if_out();
Xstatic int if_ioc();
X
Xstatic struct module_info minfo = { 518, "str_ip", 0, INFPSZ, 1024, 1024};
X
Xstatic struct qinit rinit = {
X	rput, if_in, stream_open, stream_close, NULL, &minfo, NULL
X	};
Xstatic struct qinit winit = {
X	wput, NULL, NULL, NULL, NULL, &minfo, NULL
X	};
X
Xstruct streamtab streams_ip = { &rinit, &winit, NULL, NULL };
X
Xtypedef struct {
X	queue_t *q;
X	struct ifnet i
X	} ifhead ;
X
Xstatic ifhead ifheads[NSLIP];
X
Xstatic int stream_open(q,dev,flag,sflag)
X    queue_t *q;
X    dev_t dev;
X    int flag;
X    int sflag;
X{
X    struct ifnet *ifp;
X
X    if(!suser()) {
X	u.u_error = EPERM;
X	return(OPENFAIL);
X    }
X
X    for ( dev = 0 ; dev < NSLIP ; dev++)
X	if ( !ifheads[dev].q )
X	    break;
X
X    if (dev > NSLIP)
X	return(OPENFAIL);
X
X    ifp = &ifheads[dev].i;
X    WR(q)->q_ptr = q->q_ptr = (caddr_t)&ifheads[dev];
X    ifheads[dev].q = q;
X
X    if (!ifp->if_mtu) {
X	ifp->if_name = "stream";
X	ifp->if_mtu = SLIPMTU;
X	ifp->if_flags = IFF_POINTOPOINT;
X	ifp->if_unit = dev;
X	ifp->if_ioctl = if_ioc;
X	ifp->if_output = if_out;
X	ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
X
X	if_attach(ifp);
X    }
X
X    return(ifp->if_unit);
X}
X
Xstatic int stream_close(q,flag)
X    queue_t *q;
X    int flag;
X{
X    ((ifhead *)(q->q_ptr))->q = NULL;
X    ((ifhead *)(q->q_ptr))->i.if_flags &= ~IFF_UP;
X    q->q_ptr = NULL;
X}
X
Xstatic int wput(q,mp)
X    queue_t *q;
X    mblk_t *mp;
X{
X    struct iocblk *iocp;
X
X    switch (mp->b_datap->db_type) {
X    case M_FLUSH:
X	if (*mp->b_rptr & FLUSHW)
X	    flushq(q, FLUSHDATA);
X    case M_IOCTL:
X	iocp = (struct iocblk *) mp->b_rptr;
X	switch(iocp->ioc_cmd) {
X	case SLIOGUNIT:
X	    if ((mp->b_cont = allocb(sizeof(int),BPRI_MED)) == NULL) {
X		mp->b_datap->db_type =  M_IOCNAK;
X		iocp->ioc_error = ENOSR;
X	    } else {
X		mp->b_datap->db_type = M_IOCACK;
X		*((int *)(mp->b_cont->b_wptr)) = 
X		    ((ifhead *)(q->q_ptr))->i.if_unit;
X		mp->b_cont->b_wptr += sizeof(int);
X		iocp->ioc_count = sizeof(int);
X		iocp->ioc_error = 0;
X	    }
X	    break;
X	default:
X	    putnext(q,mp);
X	    return;
X	}
X	qreply(q,mp);
X	break;
X    default:
X	putnext(q,mp);
X    }
X}
X
Xstatic int rput(q,mp)
X    queue_t *q;
X    mblk_t *mp;
X{
X    switch (mp->b_datap->db_type) {
X    case M_DATA:
X    case M_FLUSH:
X	putq(q,mp);
X	break;
X    default:
X	putnext(q,mp);
X    }
X}
X
Xstatic int if_out(ifp, m0, dst)
X    struct ifnet *ifp;
X    struct mbuf *m0;
X    struct sockaddr *dst;
X{
X    int len = 0;
X    queue_t *q = ifheads[ifp->if_unit].q;
X    struct mbuf *m;
X    mblk_t *mp;
X    int s;
X
X    if (q == 0) {
X	m_freem(m0);
X	return(EHOSTDOWN);
X    }
X
X    ifp->if_opackets++;
X    switch (dst->sa_family) {
X
X    case AF_INET:
X	for (m = m0; m!= 0 ; m = m->m_next) {
X	    len += m->m_len;
X	}
X	if ((mp = allocb(len, BPRI_MED)) == NULL) {
X	    ifp->if_oerrors++;
X	    m_freem(m0);
X	    return(ENOSR);
X	}
X	for (m = m0; m!= 0 ; m = m->m_next) {
X	    bcopy(mtod(m, u_char *),mp->b_wptr,m->m_len);
X	    mp->b_wptr += m->m_len;
X	}
X	s = splstr();
X	if (q) {
X	    if (canput(WR(q)->q_next)) {
X		putnext(WR(q),mp);
X	    } else {
X		ifp->if_oerrors++;
X		freemsg(mp);
X	    }
X	} else
X	    freemsg(mp);
X	splx(s);
X	m_freem(m0);
X	break;
X    default:
X	m_freem(m0);
X	return(EAFNOSUPPORT);
X    }
X    return(0);
X}
X
Xstatic int if_in(q)
X    queue_t *q;
X{
X    mblk_t *mp, *bp;
X    int len;
X    struct mbuf *m;
X    struct ifnet *ifp = &((ifhead*)q->q_ptr)->i;
X    int offset;
X    int s;
X
X
X    while ((mp = getq(q)) != NULL) {
X	switch (mp->b_datap->db_type) {
X	default: /* paranoid */
X	    putnext(q,mp);
X	    continue;
X	case M_FLUSH:
X	    if (*mp->b_rptr & FLUSHR)
X		flushq(q, FLUSHDATA);
X	    putnext(q,mp);
X	    continue;
X	case M_DATA:
X	    MGET(m, M_DONTWAIT, MT_DATA);	/* get an MBUF */
X	    if(!m) { /* dropit */
X		ifp->if_ierrors++;
X		freemsg(mp);
X		log(LOG_ERR,"slip: MGET FAILED\n");
X		continue;
X	    }
X
X	    len = sizeof(ifp);
X	    for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
X		len += bp->b_wptr - bp->b_rptr;
X	    }
X
X	    if (len > MLEN) {
X		if (len > MCLBYTES) {
X		    ifp->if_ierrors++;
X		    freemsg(mp);
X		    m_freem(m);
X		    continue;
X		}
X		MCLGET(m);
X		if (m->m_len == MLEN) {
X		    ifp->if_ierrors++;
X		    freemsg(mp);
X		    m_freem(m);
X		    log(LOG_ERR,"slip: MCLGET FAILED\n");
X		    continue;
X		}
X
X	    }
X	    /* assert mbuf big enough to hold whole message */
X
X	    /* copy pointer */
X	    bcopy((char*)&ifp,mtod(m,char*),offset=sizeof(ifp));
X
X	    /* copy data */
X	    for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
X		bcopy(bp->b_rptr,mtod(m,char*)+offset,bp->b_wptr - bp->b_rptr);
X		offset += bp->b_wptr - bp->b_rptr;
X		bp->b_rptr = bp->b_wptr;
X	    }
X	    m->m_len = offset;
X
X	    ifp->if_ipackets++;
X	    /* enqueue / drop */
X	    s = splimp();
X	    if (IF_QFULL(&ipintrq)) {
X		IF_DROP(&ipintrq);
X		ifp->if_ierrors++;
X		m_freem(m);
X		(void) splx(s);
X		log(LOG_ERR,"slip: IF_QFULL\n");
X	    } else {
X		IF_ENQUEUE(&ipintrq, m);
X		schednetisr(NETISR_IP);
X		(void) splx(s);
X	    }
X	    freemsg(mp);
X	}
X    }
X}
X
Xstatic int if_ioc(ifp, cmd, data)
X    struct ifnet *ifp;
X    int cmd;
X    caddr_t data;
X{
X    struct ifaddr *ifa = (struct ifaddr *)data;
X    int s;
X    int error = 0;
X
X    if (ifa == NULL)
X	return(EFAULT);
X    s = splimp();
X    switch (cmd) {
X    case SIOCSIFADDR:
X	switch (ifa->ifa_addr.sa_family) {
X	case AF_INET:
X	    ifp->if_flags |= IFF_UP;
X	    break;
X	default:
X	    error = EAFNOSUPPORT;
X	    break;
X	}
X	break;
X    case SIOCSIFDSTADDR:
X	switch (ifa->ifa_addr.sa_family) {
X	case AF_INET:
X	    break;
X	default:
X	    error = EAFNOSUPPORT;
X	    break;
X	}
X	break;
X    default:
X	error = EINVAL;
X    }
X    splx(s);
X    return(error);
X}
X#endif
SHAR_EOF
fi
exit 0
#	End of shell archive
- --
Mark Andrews, CSIRO Div Maths & Stats, PO Box 218, Lindfield, NSW, Australia.
PHONE:  +61 2 413 7058              ACSNET: marka@dmssyd.dms.oz
INTERNET: marka@syd.dms.csiro.au    UUCP: ....!uunet!syd.dms.csiro.au!marka
