home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / SUN / SLIP / CSN_SLIP.TAR / slip-4.1.1 / slipencode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-05  |  4.6 KB  |  235 lines

  1. /*
  2.  *    SLIP streams packet encoding/decoding module. SunOS 4.1.
  3.  *
  4.  *    Copyright CSIRO Division of Mathematics and Statistics 21 June 1990
  5.  *
  6.  *    Author: Mark Andrews, marka@syd.dms.csiro.au
  7.  *    
  8.  *    The encoding/decoding algorithim is derived from work by
  9.  *    Rayan Zachariassen, rayan@ai.toronto.edu.
  10.  *
  11.  *      Permission is hereby granted for this code to be distributed
  12.  *      free of charge with this copyright intact. Derived works should
  13.  *      be marked as so.
  14.  
  15.  */
  16.  
  17. #include <sys/types.h>
  18. #include <sys/stream.h>
  19. #include <sys/stropts.h>
  20. #include <sys/param.h>
  21. #include <sys/syslog.h>
  22.  
  23. #include <sys/slip.h> /* from 4.0 slip code only needed for SLIPMTU */
  24.  
  25.  
  26. typedef struct {
  27.     int inlen;
  28.     int sawescape;
  29.     int overrun;
  30.     unsigned char *dp;
  31.     unsigned char buf[SLIPMTU];
  32.     } slipb;
  33.  
  34. static int encode();
  35. static int decode();
  36. static int slopen();
  37. static int slclose();
  38. static int wput();
  39.  
  40. static struct module_info minfo = { 517, "slipe", 0, INFPSZ, 0, 0};
  41.  
  42. static struct qinit rinit = {
  43.     decode, NULL, slopen, slclose, NULL, &minfo, NULL
  44.     };
  45. static struct qinit winit = {
  46.     wput, encode, NULL, NULL, NULL, &minfo, NULL
  47.     };
  48.  
  49. struct streamtab slipencode = { &rinit, &winit, NULL, NULL };
  50.  
  51.  
  52. static int slopen(q,dev,flag,sflag)
  53.     queue_t *q;
  54.     dev_t dev;
  55.     int flag;
  56.     int sflag;
  57. {
  58.     slipb *b;
  59.     int s;
  60.  
  61.     if((b = (slipb *)kmem_alloc(sizeof(slipb))) == NULL)
  62.     return(OPENFAIL);
  63.  
  64.     b->dp = b->buf;
  65.     b->inlen = 0;
  66.     b->overrun = 0;
  67.     b->sawescape = 0;
  68.  
  69.     s = splstr(s);
  70.     OTHERQ(q)->q_ptr = q->q_ptr = (char *)b;
  71.     splx(s);
  72.  
  73.     return(0);
  74. }
  75.  
  76. static int slclose(q,flag)
  77.     queue_t *q;
  78.     int flag;
  79. {
  80.     caddr_t p = q->q_ptr;
  81.     int s;
  82.  
  83.     s = splstr();
  84.     OTHERQ(q)->q_ptr = q->q_ptr = 0;
  85.     kmem_free(p,sizeof(slipb));
  86.     splx(s);
  87. }
  88.  
  89. static int wput(q,mp)
  90.     queue_t *q;
  91.     mblk_t *mp;
  92. {
  93.     switch (mp->b_datap->db_type) {
  94.     case M_DATA:
  95.     case M_FLUSH:
  96.     putq(q,mp);
  97.     break;
  98.     default:
  99.     putnext(q,mp);
  100.     }
  101. }
  102.  
  103. static int encode(q)
  104.     queue_t *q;
  105. {
  106.     mblk_t *mp, *bp, *nb;
  107.     int len;
  108.     unsigned char *rp;
  109.     unsigned char ch;
  110.  
  111.  
  112.     while ((mp = getq(q)) != NULL) {
  113.     switch (mp->b_datap->db_type) {
  114.     default: /* paranoid */
  115.         putnext(q,mp);
  116.         continue;
  117.     case M_FLUSH:
  118.         if (*mp->b_rptr & FLUSHW)
  119.         flushq(q, FLUSHDATA);
  120.         putnext(q,mp);
  121.         continue;
  122.     case M_DATA:
  123.         if(!canput(q->q_next)) {
  124.         putbq(q,mp);
  125.         return;
  126.         }
  127.         len = 2;
  128.         for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
  129.         rp = bp->b_rptr;
  130.         while (rp < bp->b_wptr) {
  131.             ch = *rp++;
  132.             len++;
  133.             if ((ch == ESC) || (ch == END))
  134.             len++;
  135.         }
  136.         }
  137.         if ((nb = allocb(len,BPRI_MED)) == NULL) {
  138.         log(LOG_DEBUG,"slipencode: unable to allocate write buffer\n");
  139.            freemsg(mp);
  140.            continue;
  141.         }
  142.         *nb->b_wptr++ = END;
  143.         for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
  144.         rp = bp->b_rptr;
  145.         while (rp < bp->b_wptr) {
  146.             ch = *rp++;
  147.             if (ch == END) {
  148.             *nb->b_wptr++ = ESC;
  149.             *nb->b_wptr++ = ESC_END;
  150.             } else if ( ch == ESC ) {
  151.             *nb->b_wptr++ = ESC;
  152.             *nb->b_wptr++ = ESC_ESC;
  153.             } else
  154.             *nb->b_wptr++ = ch;
  155.         }
  156.         }
  157.         *nb->b_wptr++ = END;
  158.         putnext(q,nb);
  159.         freemsg(mp);
  160.     }
  161.     }
  162. }
  163.  
  164. static int decode(q,mp)
  165.     queue_t *q;
  166.     mblk_t *mp;
  167. {
  168.     slipb *b = (slipb *)q->q_ptr;
  169.     mblk_t *bp, *nb;
  170.     unsigned char *rp;
  171.     unsigned char ch;
  172.  
  173.     switch (mp->b_datap->db_type) {
  174.     default:
  175.     putnext(q,mp);
  176.     break;
  177.     case M_FLUSH:
  178.     if (*mp->b_rptr & FLUSHR)
  179.         flushq(q, FLUSHDATA);
  180.     putnext(q,mp);
  181.     break;
  182.     case M_DATA:
  183.     for (bp = mp; bp != 0 ; bp = bp->b_cont ) {
  184.         rp = bp->b_rptr;
  185.         while (rp < bp->b_wptr) {
  186.         ch = *rp++;
  187.         if (b->sawescape) { /* undo escape */
  188.             b->sawescape = 0;
  189.             if ( ch == ESC_END )
  190.             ch = END;
  191.             else if ( ch == ESC_ESC )
  192.             ch = ESC;
  193.         } else if (ch == END) { /* start/end character */
  194.             if (b->overrun) { /* set up to recieve new packet */
  195.             b->overrun = 0;
  196.             b->inlen = 0;
  197.             continue;
  198.             }
  199.             if (b->inlen == 0) /* start flag ignore */
  200.             continue;
  201.  
  202.             /* build new message */
  203.             if ((nb = allocb(b->inlen,BPRI_MED)) == NULL) {
  204.                log(LOG_DEBUG,"slipencode: unable to allocate read buffer dropping packet\n");
  205.                b->inlen = 0;
  206.                b->dp = b->buf;
  207.                continue;
  208.             }
  209.             bcopy(b->buf, nb->b_wptr, b->inlen);
  210.             nb->b_wptr += b->inlen;
  211.             putnext(q,nb);
  212.  
  213.             b->inlen = 0;    /* setup for next packet */
  214.             b->dp = b->buf;
  215.             continue;
  216.  
  217.         } else if (ch == ESC) {
  218.             b->sawescape = 1;
  219.             continue;
  220.         }
  221.         if (++(b->inlen) > SLIPMTU) {
  222.             if(!b->overrun)
  223.             log(LOG_ERR,"slipencode: overrun\n");
  224.             b->overrun = 1;
  225.             b->dp = b->buf;
  226.             continue;
  227.         }
  228.         *(b->dp)++ = ch;
  229.         }
  230.         bp->b_rptr = rp;
  231.     }
  232.     freemsg(mp);
  233.     }
  234. }
  235.