home *** CD-ROM | disk | FTP | other *** search
- /*
- * SLIP streams packet encoding/decoding module. SunOS 4.1.
- *
- * Copyright CSIRO Division of Mathematics and Statistics 21 June 1990
- *
- * Author: Mark Andrews, marka@syd.dms.csiro.au
- *
- * The encoding/decoding algorithim is derived from work by
- * Rayan Zachariassen, rayan@ai.toronto.edu.
- *
- * Permission is hereby granted for this code to be distributed
- * free of charge with this copyright intact. Derived works should
- * be marked as so.
-
- */
-
- #include <sys/types.h>
- #include <sys/stream.h>
- #include <sys/stropts.h>
- #include <sys/param.h>
- #include <sys/syslog.h>
-
- #include <sys/slip.h> /* from 4.0 slip code only needed for SLIPMTU */
-
-
- typedef struct {
- int inlen;
- int sawescape;
- int overrun;
- unsigned char *dp;
- unsigned char buf[SLIPMTU];
- } slipb;
-
- static int encode();
- static int decode();
- static int slopen();
- static int slclose();
- static int wput();
-
- static struct module_info minfo = { 517, "slipe", 0, INFPSZ, 0, 0};
-
- static struct qinit rinit = {
- decode, NULL, slopen, slclose, NULL, &minfo, NULL
- };
- static struct qinit winit = {
- wput, encode, NULL, NULL, NULL, &minfo, NULL
- };
-
- struct streamtab slipencode = { &rinit, &winit, NULL, NULL };
-
-
- static int slopen(q,dev,flag,sflag)
- queue_t *q;
- dev_t dev;
- int flag;
- int sflag;
- {
- slipb *b;
- int s;
-
- if((b = (slipb *)kmem_alloc(sizeof(slipb))) == NULL)
- return(OPENFAIL);
-
- b->dp = b->buf;
- b->inlen = 0;
- b->overrun = 0;
- b->sawescape = 0;
-
- s = splstr(s);
- OTHERQ(q)->q_ptr = q->q_ptr = (char *)b;
- splx(s);
-
- return(0);
- }
-
- static int slclose(q,flag)
- queue_t *q;
- int flag;
- {
- caddr_t p = q->q_ptr;
- int s;
-
- s = splstr();
- OTHERQ(q)->q_ptr = q->q_ptr = 0;
- kmem_free(p,sizeof(slipb));
- splx(s);
- }
-
- static int wput(q,mp)
- queue_t *q;
- mblk_t *mp;
- {
- switch (mp->b_datap->db_type) {
- case M_DATA:
- case M_FLUSH:
- putq(q,mp);
- break;
- default:
- putnext(q,mp);
- }
- }
-
- static int encode(q)
- queue_t *q;
- {
- mblk_t *mp, *bp, *nb;
- int len;
- unsigned char *rp;
- unsigned char ch;
-
-
- while ((mp = getq(q)) != NULL) {
- switch (mp->b_datap->db_type) {
- default: /* paranoid */
- putnext(q,mp);
- continue;
- case M_FLUSH:
- if (*mp->b_rptr & FLUSHW)
- flushq(q, FLUSHDATA);
- putnext(q,mp);
- continue;
- case M_DATA:
- if(!canput(q->q_next)) {
- putbq(q,mp);
- return;
- }
- len = 2;
- for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
- rp = bp->b_rptr;
- while (rp < bp->b_wptr) {
- ch = *rp++;
- len++;
- if ((ch == ESC) || (ch == END))
- len++;
- }
- }
- if ((nb = allocb(len,BPRI_MED)) == NULL) {
- log(LOG_DEBUG,"slipencode: unable to allocate write buffer\n");
- freemsg(mp);
- continue;
- }
- *nb->b_wptr++ = END;
- for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
- rp = bp->b_rptr;
- while (rp < bp->b_wptr) {
- ch = *rp++;
- if (ch == END) {
- *nb->b_wptr++ = ESC;
- *nb->b_wptr++ = ESC_END;
- } else if ( ch == ESC ) {
- *nb->b_wptr++ = ESC;
- *nb->b_wptr++ = ESC_ESC;
- } else
- *nb->b_wptr++ = ch;
- }
- }
- *nb->b_wptr++ = END;
- putnext(q,nb);
- freemsg(mp);
- }
- }
- }
-
- static int decode(q,mp)
- queue_t *q;
- mblk_t *mp;
- {
- slipb *b = (slipb *)q->q_ptr;
- mblk_t *bp, *nb;
- unsigned char *rp;
- unsigned char ch;
-
- switch (mp->b_datap->db_type) {
- default:
- putnext(q,mp);
- break;
- case M_FLUSH:
- if (*mp->b_rptr & FLUSHR)
- flushq(q, FLUSHDATA);
- putnext(q,mp);
- break;
- case M_DATA:
- for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
- rp = bp->b_rptr;
- while (rp < bp->b_wptr) {
- ch = *rp++;
- if (b->sawescape) { /* undo escape */
- b->sawescape = 0;
- if ( ch == ESC_END )
- ch = END;
- else if ( ch == ESC_ESC )
- ch = ESC;
- } else if (ch == END) { /* start/end character */
- if (b->overrun) { /* set up to recieve new packet */
- b->overrun = 0;
- b->inlen = 0;
- continue;
- }
- if (b->inlen == 0) /* start flag ignore */
- continue;
-
- /* build new message */
- if ((nb = allocb(b->inlen,BPRI_MED)) == NULL) {
- log(LOG_DEBUG,"slipencode: unable to allocate read buffer dropping packet\n");
- b->inlen = 0;
- b->dp = b->buf;
- continue;
- }
- bcopy(b->buf, nb->b_wptr, b->inlen);
- nb->b_wptr += b->inlen;
- putnext(q,nb);
-
- b->inlen = 0; /* setup for next packet */
- b->dp = b->buf;
- continue;
-
- } else if (ch == ESC) {
- b->sawescape = 1;
- continue;
- }
- if (++(b->inlen) > SLIPMTU) {
- if(!b->overrun)
- log(LOG_ERR,"slipencode: overrun\n");
- b->overrun = 1;
- b->dp = b->buf;
- continue;
- }
- *(b->dp)++ = ch;
- }
- bp->b_rptr = rp;
- }
- freemsg(mp);
- }
- }
-