jml@tw-rnd.SanDiego.NCR.COM (Michael Lodman) (12/12/89)
After numerous mail requests, I decided the easiest thing to do would be to just post this source for SL/IP. Disclaimer: I am nothing but a user of this code. cut here------------------------cut here------------------------cut here # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by John Ioannidis <ji@close> on Wed Oct 18 11:18:41 1989 # # This archive contains: # README Driver.c Master space.c # netd.cf node.d-slip sdevice.d-slip slattach.c # # Modification/access file times will be preserved. # Error checking via wc(1) will be performed. # Error checking via sum(1) will be performed. LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH if sum -r </dev/null >/dev/null 2>&1 then sumopt='-r' else sumopt='' fi echo x - README cat >README <<'@EOF' It is assumed that you more or less know how to install a driver in a System V machine and rebuild the kernel. The instructions here are for Interactive's 386/ix -- your milage may vary. * create /etc/conf/pack.d/slip/. Copy Driver.c and space.c there. Compile Driver.c (cc -c Driver.c) and leave space.c intact. * Put the following line in a /etc/conf/sdevice.d/slip ----------------------cut-here------------------------- slip Y 1 0 0 0 0 0 0 0 ----------------------cut-here------------------------- * Put the following two lines in /etc/conf/node.d/slip ----------------------cut-here------------------------- slip slip c 0 slip sliplisten c 1 ----------------------cut-here------------------------- * Put the folloing line in a file called Master in /tmp (or in /etc/conf/pack.d/slip) and run /etc/conf/bin/idinstall -a -m -k slip on it. ----------------------cut-here------------------------- slip - iSco slip 0 0 0 32 -1 ----------------------cut-here------------------------- This will install it in /etc/conf/cf.d/mdevice. Now run kconfig; this is by far the easiest way of reconfiguring a kernel. Just select '2' (configure a new kernel), followed by a few yes'es. If all goes well, it should build a new kernel, and when you reboot, create /dev/slip and /dev/sliplisten in /dev. Now you have to change /etc/netd.cf. Edit the one provided here. What we are doing is we are linking /dev/slip right under /dev/ip, the same way /dev/lo and /dev/arp are linked. Finally, compile slattach.c, connect your machine to another machine that groks slip, and fire up netd and slattach. Network services, pinging and gatewaying should all work. If you want to turn on debugging, run slattach with the environment variable DEBUGSLIP set to 1 (for debugging the STREAMS module), 2 (for debugging slattach) or 3 (for debugging both). Setting it to zero will disable both. Things I haven't done: * Change the MTU from 576 to something more reasonable (like 1500) * Set the POINTOPOINT flag in the if structure (I have yet to figure out how to do that in a clean way) * Implement the DLGSTAT ioctl so that netstat -i will work properly. * Clean up the code; it contains too many debugging hooks right now. * ... This is not the cleanest code I have ever written, but until last month I had never even used a System-V machine, let alone written a STREAMS device driver for it. The driver itself took me less than a week to write, in case it matters. I could have banged on the driver for another week and then released a cleaner version, but I think that a lot of people want SLIP for their machines and releasing it now will enable me to have it tested on a variety of platforms and have it debugged faster. In case you need to reach me, you can send me e-mail at ji@cs.columbia.edu (but you already know that). This is by far the easiest way to get in touch with me. If you feel like calling me, my phone number is (212) 854-5510, and I'm there from noon to the wee hours in the morning (but not continuously!) Finally, if you are, or know of, a good Un*x kernel hacker who wants to work for 12-18 months on a REALLY exciting project, drop me a line. /ji @EOF set `sum $sumopt <README`; if test $1 -ne 2293 then echo ERROR: README checksum is $1 should be 2293 fi set `wc -lwc <README` if test $1$2$3 != 735223172 then echo ERROR: wc results of README are $* should be 73 522 3172 fi touch -m 1018002989 README touch -a 1018111389 README chmod 666 README echo x - Driver.c cat >Driver.c <<'@EOF' /* * SLIP driver for 386/ix * * Copyright (C) 1989 by John Ioannidis, ji@cs.columbia.edu * * Permission is granted to use, modify and copy this code * provided you don't make a profit out of it and that you * keep the copyright notice intact. */ #include "sys/types.h" #include "sys/param.h" #include "sys/sysmacros.h" #include "sys/stream.h" #include "sys/stropts.h" #include "sys/dir.h" #include "sys/signal.h" #include "sys/user.h" #include "sys/errno.h" #include "sys/lihdr.h" #include "sys/socket.h" #include "netinet/in_systm.h" #include "netinet/in.h" #include "netinet/ip.h" #include "net/if.h" static struct module_info minfo = { 0, "slip", 0, INFPSZ, 512, 128 }; static int slipopen(), slipclose(), slipwput(), slipwsrv(), sliprsrv(); static struct qinit rinit = { NULL, sliprsrv, slipopen, slipclose, NULL, &minfo, NULL }; static struct qinit winit = { slipwput, slipwsrv, NULL, NULL, NULL, &minfo, NULL }; struct streamtab slipinfo = { &rinit, &winit, NULL, NULL }; struct slip { short boundp; short slipd; queue_t *oqptr; }; extern struct slip slip_slip[]; extern int slip_cnt; #define SETDEBUG (('J'<<8) | 1) static int slipdebug=0; static int slipopen(q, dev, flag, sflag) queue_t *q; { struct slip *slip; /* * If CLONEOPEN, return an error. We are only supposed * to be called from the networking code as minor 0 * and from the user-level loopback as minor 1. */ #ifdef DEBUGSLIP if (slipdebug) printf("slipopen(0x%x, %d, 0%o, 0%o)\n", q, dev, flag, sflag); #endif if (sflag == CLONEOPEN) return OPENFAIL; if (q->q_ptr) { #ifdef DEBUGSLIP if (slipdebug) printf("slipopen: attempted reopen slip/%d\n", dev); #endif return OPENFAIL; } switch (minor(dev)) { case 1: /* user side */ slip = &slip_slip[1]; q->q_ptr = (caddr_t) slip; WR(q)->q_ptr = (caddr_t) slip; slip_slip[0].oqptr = q; slip->slipd = 1; slip->boundp = 0; return 1; break; case 0: slip = &slip_slip[0]; q->q_ptr = (caddr_t) slip; WR(q)->q_ptr = (caddr_t) slip; slip_slip[1].oqptr = q; slip->slipd = 0; slip->boundp = 0; return 0; break; default: #ifdef DEBUGSLIP if (slipdebug) printf("slipopen: bad minor device slip/%d\n", dev); #endif return OPENFAIL; } /*NOTREACHED*/ } /* * the write-side put proc. This is where we handle all the * requests from the /dev/ip driver. Look up the document for * DLI for explanations. */ static int slipwput(q, mp) queue_t *q; mblk_t *mp; { struct ifnet *myif; mblk_t *mpc; extern struct ifnet *ifnet; int i; register struct slip *slip; slip = (struct slip*)q->q_ptr; /* recover our private d/s */ switch (mp->b_datap->db_type) { case M_PROTO: case M_PCPROTO: { register union DL_primitives *lir; lir = (union DL_primitives *)mp->b_rptr; switch (lir->prim_type) { case DL_BIND_REQ: #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: DL_BIND_REQ: sap=%x\n", slip->slipd, lir->bind_req.LLC_sap); #endif mp->b_datap->db_type = M_PCPROTO; lir->bind_ack.PRIM_type = DL_BIND_ACK; /* lir->bind_ack.LLC_sap = 0; */ lir->bind_ack.ADDR_length = 0; lir->bind_ack.ADDR_offset = 0; lir->bind_ack.GROWTH_field[0] = 0x1234; lir->bind_ack.GROWTH_field[1] = 0x5678; mp->b_wptr = mp->b_rptr + DL_BIND_ACK_SIZE; qreply(q, mp); break; case DL_UNBIND_REQ: #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: DL_UNBIND_REQ\n", slip->slipd); #endif mp->b_datap->db_type = M_PCPROTO; lir->ok_ack.PRIM_type = DL_OK_ACK; lir->ok_ack.CORRECT_prim = DL_UNBIND_REQ; mp->b_wptr = mp->b_rptr + DL_OK_ACK_SIZE; qreply(q, mp); break; case DL_INFO_REQ: #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: DL_INFO_REQ\n", slip->slipd); #endif mp->b_datap->db_type = M_PCPROTO; lir->info_ack.PRIM_type = DL_INFO_ACK; lir->info_ack.SDU_max = 1024; lir->info_ack.SDU_min = sizeof(struct ip); lir->info_ack.ADDR_length = 0; lir->info_ack.SUBNET_type = 0; lir->info_ack.SERV_class = 0; lir->info_ack.CURRENT_state = DL_IDLE; mp->b_wptr = mp->b_rptr + DL_INFO_ACK_SIZE; qreply(q, mp); break; case DL_UNITDATA_REQ: #ifdef DEBUGSLIP if (slipdebug) { printf("slipwput%d: DL_UNITDATA_REQ: len=%d off=%d sclass=%d filler=%d :", slip->slipd, lir->data_req.RA_length, lir->data_req.RA_offset, lir->data_req.SERV_class, lir->data_req.FILLER_field); for (i=lir->data_req.RA_offset; i<lir->data_req.RA_offset + lir->data_req.RA_length; i++) printf("%d:", ((char *)&(lir->data_req))[i]); printf("\n"); } #endif if (mp->b_cont) { #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: putting cont msg to the Q\n", slip->slipd); #endif putq(q, mp->b_cont); } else { printf("slipwput: DL_UNITDATA_REQ: error! no continuation message!\n"); freemsg(mp); } break; default: printf("slipwput%d: prim_type=0%o, putting in Q\n", slip->slipd, lir->prim_type); putq(q, mp); } } break; case M_IOCTL: { struct iocblk *iocp; int error; iocp = (struct iocblk *)mp->b_rptr; switch (iocp->ioc_cmd) { #ifdef DEBUGSLIP case SETDEBUG: if (iocp->ioc_count != sizeof(int)) goto iocnak; slipdebug = *(int *)mp->b_cont->b_rptr; mp->b_datap->db_type = M_IOCACK; iocp->ioc_count = 0; qreply(q, mp); break; #endif default: iocnak: error = EINVAL; #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: M_IOCTL: bad ioctl %x\n", slip->slipd, iocp->ioc_cmd); #endif mp->b_datap->db_type = M_IOCNAK; iocp->ioc_error = error; qreply(q, mp); } break; } case M_FLUSH: #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: M_FLUSH: flushing\n", slip->slipd); #endif if (*mp->b_rptr & FLUSHW) flushq(q, 0); if (*mp->b_rptr & FLUSHR) { flushq(RD(q), 0); *mp->b_rptr &= ~FLUSHW; qreply(q, mp); } else freemsg(mp); break; case M_DATA: { register union DL_primitives *lir; #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: M_DATA message\n", slip->slipd); #endif /* * the only way we can get here is by having the * user process pump us a datagram. Create a * contol part and send up a DL_UNITDATA_IND * message. */ mpc = allocb(DL_UNITDATA_IND_SIZE + 12, BPRI_MED); if (mpc == NULL) { printf("slipwput%d: M_DATA: can't allocb control msgs\n", slip->slipd); return; } mpc->b_datap->db_type = M_PCPROTO; lir = (union DL_primitives *)mpc->b_wptr; lir->data_ind.PRIM_type = DL_UNITDATA_IND; lir->data_ind.RA_length = lir->data_ind.LA_length = 6; lir->data_ind.RA_offset = DL_UNITDATA_IND_SIZE; lir->data_ind.LA_offset = DL_UNITDATA_IND_SIZE + 6; lir->data_ind.SERV_class = 0; mpc->b_wptr[DL_UNITDATA_IND_SIZE+0] = 0x7e; mpc->b_wptr[DL_UNITDATA_IND_SIZE+1] = 0x00; mpc->b_wptr[DL_UNITDATA_IND_SIZE+2] = 0x00; mpc->b_wptr[DL_UNITDATA_IND_SIZE+3] = 0x02; mpc->b_wptr[DL_UNITDATA_IND_SIZE+4] = 0x02; mpc->b_wptr[DL_UNITDATA_IND_SIZE+5] = 0x00; mpc->b_wptr[DL_UNITDATA_IND_SIZE+6] = 0x7e; mpc->b_wptr[DL_UNITDATA_IND_SIZE+7] = 0x00; mpc->b_wptr[DL_UNITDATA_IND_SIZE+8] = 0x00; mpc->b_wptr[DL_UNITDATA_IND_SIZE+9] = 0x01; mpc->b_wptr[DL_UNITDATA_IND_SIZE+10] = 0x02; mpc->b_wptr[DL_UNITDATA_IND_SIZE+11] = 0x00; mpc->b_wptr += DL_UNITDATA_IND_SIZE + 12; mpc->b_cont = mp; /* putq(q, mpc); */ putnext(slip->oqptr, mpc); break; } default: /* * if this stream isn't connected, send an M_ERROR upstream */ if (slip->oqptr == NULL) { putctl1(RD(q)->q_next, M_ERROR, ENXIO); freemsg(mp); break; } #ifdef DEBUGSLIP if (slipdebug) printf("slipwput%d: DEFAULT (data?) message\n", slip->slipd); #endif putq(q, mp); } } static int slipwsrv(q) register queue_t *q; { mblk_t *mp; register struct slip *slip; slip = (struct slip *)q->q_ptr; #ifdef DEBUGSLIP if (slipdebug) printf("slipwsrv%d: called!\n", slip->slipd); #endif while ((mp = getq(q)) != NULL) { /* * Check is we can put the message up the other * stream's read queue */ if (mp->b_datap->db_type <= QPCTL && !canput(slip->oqptr->q_next)) { #ifdef DEBUGSLIP if (slipdebug) printf("slipwsrv%d: blocked, putting back\n",slip->slipd); #endif putbq(q, mp); break; } #ifdef DEBUGSLIP if (slipdebug) printf("slipwsrv%d: pulled sth from the Q, sending...\n", slip->slipd); #endif putnext(slip->oqptr, mp); } } static int sliprsrv(q) queue_t *q; { /* * enter only when "back enabled" by flow control */ struct slip *slip; #ifdef DEBUGSLIP if (slipdebug) printf("sliprsrv%d: called!\n", slip->slipd); #endif slip = (struct slip *)q->q_ptr; if (slip->oqptr == NULL) return; /* manually enable write service procedure */ qenable(WR(slip->oqptr)); } static int slipclose(q) queue_t *q; { register struct slip *slip; slip = (struct slip *)q->q_ptr; slip->boundp = NULL; #ifdef DEBUGSLIP if (slipdebug) printf("slipclose%d: called!\n", slip->slipd); #endif } #ifdef notdef for (myif=ifnet; myif; myif = myif->if_next) { #ifdef DEBUGSLIP printf("slipwput: found %s\n", myif->if_name); #endif if (myif->if_name && !(strcmp(myif->if_name, "slip0"))) { myif->if_flags |= IFF_POINTOPOINT; break; } } #endif @EOF set `sum $sumopt <Driver.c`; if test $1 -ne 47282 then echo ERROR: Driver.c checksum is $1 should be 47282 fi set `wc -lwc <Driver.c` if test $1$2$3 != 454106010378 then echo ERROR: wc results of Driver.c are $* should be 454 1060 10378 fi touch -m 1018002989 Driver.c touch -a 1018111389 Driver.c chmod 666 Driver.c echo x - Master cat >Master <<'@EOF' slip - iSco slip 0 0 0 32 -1 @EOF set `sum $sumopt <Master`; if test $1 -ne 53130 then echo ERROR: Master checksum is $1 should be 53130 fi set `wc -lwc <Master` if test $1$2$3 != 1930 then echo ERROR: wc results of Master are $* should be 1 9 30 fi touch -m 1018002989 Master touch -a 1018111389 Master chmod 666 Master echo x - space.c cat >space.c <<'@EOF' /* * SLIP driver for 386/ix * * Copyright (C) 1989 by John Ioannidis, ji@cs.columbia.edu * * Permission is granted to use, modify and copy this code * provided you don't make a profit out of it and that you * keep the copyright notice intact. */ #include "sys/types.h" #include "sys/param.h" #include "sys/sysmacros.h" #include "sys/stream.h" #include "sys/stropts.h" #include "sys/dir.h" #include "sys/signal.h" #include "sys/user.h" #include "sys/errno.h" #include "config.h" struct slip { short openp; short slipd; queue_t *oqptr; }; struct slip slip_slip[SLIP_MAXSUB]; int slip_cnt = SLIP_MAXSUB; @EOF set `sum $sumopt <space.c`; if test $1 -ne 25856 then echo ERROR: space.c checksum is $1 should be 25856 fi set `wc -lwc <space.c` if test $1$2$3 != 3584622 then echo ERROR: wc results of space.c are $* should be 35 84 622 fi touch -m 1018002989 space.c touch -a 1018111489 space.c chmod 666 space.c echo x - netd.cf cat >netd.cf <<'@EOF' # @(#)netd.cf 1.4 - 88/11/15 # # This is a configuration file for host-based # TCP/IP using the wd ethernet interface # # open control streams for transport protocols tcp = "/dev/tcp" udp = "/dev/udp" # open an IP stream for each transport protocol ip_tcp = "/dev/ip" nsap 6 # bind stream to TCP protocol id ip_udp = "/dev/ip" nsap 17 # bind stream to UDP protocol id # open ARP for ethernet use arp = "/dev/arp" lsap 0x800 # open link level devices wd_arp = "/dev/wd" lsap 0x806 # stream for ARP messages wd_ip = "/dev/wd" lsap 0x800 # stream for IP messages loop = "/dev/lo" lsap 0x800 # stream for loopback driver loslip = "/dev/slip" lsap 0x800 # ji's sample driver # put it together link ip_tcp under tcp link ip_udp under udp # names must not assume a unit number so use as part of name link loop under ip_tcp name "lo0" link arp under ip_tcp name "wd0" link loslip under ip_tcp name "slip0" link wd_arp under arp type 0x101 link wd_ip under arp type 0x1 # initial configuration of interfaces ifconfig "wd0" toshiba1 up ifconfig "lo0" localhost up ifconfig "slip0" 126.0.0.1 126.0.0.2 up @EOF set `sum $sumopt <netd.cf`; if test $1 -ne 27466 then echo ERROR: netd.cf checksum is $1 should be 27466 fi set `wc -lwc <netd.cf` if test $1$2$3 != 391971126 then echo ERROR: wc results of netd.cf are $* should be 39 197 1126 fi touch -m 1018002989 netd.cf touch -a 1018111489 netd.cf chmod 666 netd.cf echo x - node.d-slip cat >node.d-slip <<'@EOF' slip slip c 0 slip sliplisten c 1 @EOF set `sum $sumopt <node.d-slip`; if test $1 -ne 26127 then echo ERROR: node.d-slip checksum is $1 should be 26127 fi set `wc -lwc <node.d-slip` if test $1$2$3 != 2835 then echo ERROR: wc results of node.d-slip are $* should be 2 8 35 fi touch -m 1018002989 node.d-slip touch -a 1018111489 node.d-slip chmod 666 node.d-slip echo x - sdevice.d-slip cat >sdevice.d-slip <<'@EOF' slip Y 1 0 0 0 0 0 0 0 @EOF set `sum $sumopt <sdevice.d-slip`; if test $1 -ne 31828 then echo ERROR: sdevice.d-slip checksum is $1 should be 31828 fi set `wc -lwc <sdevice.d-slip` if test $1$2$3 != 11023 then echo ERROR: wc results of sdevice.d-slip are $* should be 1 10 23 fi touch -m 1018002989 sdevice.d-slip touch -a 1018111489 sdevice.d-slip chmod 666 sdevice.d-slip echo x - slattach.c cat >slattach.c <<'@EOF' #include <sys/types.h> #include <sys/stropts.h> #include <sys/lihdr.h> #include <stdio.h> #include <ctype.h> #include <termio.h> #define isdot(_x) (((_x)&0x80)|!(isprint(_x))) #define SLIPEND (0300) #define SLIPESC (0333) #define SLIPESC_END (0334) #define SLIPESC_ESC (0335) #define SETDEBUG (('J'<<8) | 1) main(argc, argv) int argc; char **argv; { int fd, tfd, nr, debugfl; int flags, retval, i, inescape, debugon; unsigned char ibuf[2048], obuf[2048]; unsigned char *ib, *ob; char *ev; struct termio tio; struct strbuf ctlptr, dataptr; struct strioctl sctl; struct DL_unitdata_ind rply; tfd = open("/dev/tty00", 2); if (tfd < 0) perror("/dev/tty00"), exit(); tio.c_iflag = 0; tio.c_oflag = 0; tio.c_cflag = B9600 | CS8 | CREAD; tio.c_lflag = 0; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; if (ioctl(tfd, TCSETA, &tio) < 0) perror("ioctl"), exit(); fd = open("/dev/sliplisten", 2); if (fd < 0) perror("/dev/sliplisten:"), exit(); if (ev = (char *)getenv("DEBUGSLIP")) { debugfl = atoi(ev); debugon = debugfl & 2; debugfl &= 1; sctl.ic_cmd = SETDEBUG; sctl.ic_timout = 0; sctl.ic_dp = (char *)&debugfl; sctl.ic_len = 4; if (ioctl(fd, I_STR, &sctl) < 0) perror("SETDEBUG"); } if (fork()) { printf("sliplisten: reader: starting up\n"); ob = obuf; for(;;) { nr = read(tfd, ibuf,2048); write(1, ".", 1); inescape = 0; if (nr <= 0) perror("reading from tty"), exit(); ib = ibuf; for (i=0; i<nr; i++) { *ob = *ib++; if (!inescape) { if (*ob == SLIPESC) { if (debugon) printf("reader: ESC\n"); inescape = 1; continue; } else if (*ob == SLIPEND) { if (debugon) printf("reader: END\n"); dataptr.buf = (char *)obuf; dataptr.len = ob - obuf; ob = obuf; if (dataptr.len > 0) { if (debugon) xdump(dataptr.buf, dataptr.len, "sending to IP"); if (putmsg(fd, NULL, &dataptr, 0) < 0) perror("reader: putmsg"); } continue; } else { ob++; inescape = 0; } } else { if (*ob == SLIPESC_END) *ob++ = SLIPEND; else if (*ob == SLIPESC_ESC) *ob++ = SLIPESC; else ob++; } } } } else /* CHILD */ { printf("sliplisten: writer: starting up\n"); for(;;) { dataptr.maxlen = 2048; dataptr.len = 0; dataptr.buf = (char *)ibuf; flags = 0; if ((retval = getmsg(fd, NULL, &dataptr, &flags)) < 0) { perror("getmsg"); continue; } write(1, "+", 1); if (dataptr.len > 0) { ib = ibuf; ob = obuf; *ob++ = SLIPEND; for (i=0; i<dataptr.len; i++) { if (*ib == SLIPEND) { *ob++ = SLIPESC; *ob++ = SLIPESC_END; ib++; } else if (*ib == SLIPESC) { *ob++ = SLIPESC; *ob++ = SLIPESC_ESC; ib++; } else *ob++ = *ib++; } *ob++ = SLIPEND; if (debugon) xdump(obuf, ob-obuf, "sending to SLIP"); write(tfd, obuf, ob-obuf); } } } } /* * NAME * xdump -- make a hex dump of a region in memory * * SYNOPSIS * xdump(base, length, title) * caddr_t base; * int length; * char *title; */ static char line[80]; static char hd[17]="0123456789ABCDEF"; #define HI(_x) (hd[((_x)>>4)&0xF]) #define LO(_x) (hd[(_x)&0xF]) xdump(base, length, title) caddr_t base; int length; char *title; { register char *bp, *hp, *cp; register int cnt; printf("%s\n", title); bp = base; hp = line; cp = line+50; for (cnt=80; cnt; line[--cnt]=' ') ; line[49] = line[66] = '*'; line[67] = '\0'; while(length-- > 0) { *hp++ = HI(*bp); *hp++ = LO(*bp); hp++; *cp++ = isdot(*bp)?'.':(*bp); bp++; if (++cnt == 16) { cnt = 0; hp = line; cp = line+50; puts(line); } } if (cnt) { while (cnt++ < 16) { *hp++=' '; *hp++=' '; *hp++=' '; *cp++=' '; } puts(line); } return 0; } @EOF set `sum $sumopt <slattach.c`; if test $1 -ne 6126 then echo ERROR: slattach.c checksum is $1 should be 6126 fi set `wc -lwc <slattach.c` if test $1$2$3 != 2535454072 then echo ERROR: wc results of slattach.c are $* should be 253 545 4072 fi touch -m 1018111689 slattach.c touch -a 1018111589 slattach.c chmod 666 slattach.c exit 0 -- +-----------------------------------------------------------+ | Michael Lodman Mike.Lodman@SanDiego.NCR.COM | | NCR Corporation - Distributed Systems Lab - San Diego | | 9900 Old Grove Rd. San Diego, CA. 92131 (619) 693-5353 | +-----------------------------------------------------------+
izen@amelia.nas.nasa.gov (Steven H. Izen) (12/13/89)
In article <179@tw-rnd.SanDiego.NCR.COM> jml@tw-rnd.SanDiego.NCR.COM (Michael Lodman) writes: >After numerous mail requests, I decided the easiest thing to do would >be to just post this source for SL/IP. > >Disclaimer: I am nothing but a user of this code. > [ sl/ip source deleted] I downloaded the source, and tried building it. It didn't compile because I was missing some header files since I currently don't have tcp/ip installed. I found copies of the missing headers on the 386/ix distribution disks for micom interlan tcp/ip. After I installed them in the appropriate directories the driver compiled. At this point I am baffled. I know how to patch the set of /etc/conf files and rebuild my kernel. That's not what is troubling me. It's the step after that. Since I don't have tcp/ip on my machine, I don't have any of the daemons or setup files referred to. So what do I do? Can I get sl/ip up without having tcp/ip as well? Do I have to install the tcp/ip first, even though I have no ethernet card? Any help would be greatly appreciated. Thanx (in advance, of course.) -- Steve Izen: {sun,uunet}!cwjcc!skybridge!izen386!steve / Quote corner: or steve%izen386.uucp@skybridge.scl.cwru.edu / or izen@cwru.cwru.edu /-------------------------/ My second bike is a car. | The problem is that I *was* paying attention.
plocher@sally.Sun.COM (John Plocher) (12/15/89)
+-- In <4189@amelia.nas.nasa.gov> izen@cwru.cwru.edu (Steven H. Izen) writes | So what do I do? Can I get sl/ip up without having tcp/ip as well? Do I | have to install the tcp/ip first, even though I have no ethernet card? +-- Since SL/IP is just a wrapper for TCP/IP to allow them to be sent over serial lines, it doesn't make sense to use it without TCP/IP. -John Plocher