home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / misc / tcpipsrc / ppp.c < prev    next >
C/C++ Source or Header  |  1991-01-26  |  21KB  |  803 lines

  1. /*
  2.  *  PPP.C    -- Send and receive datagrams on serial lines with
  3.  *           Point-to-Point Protocol
  4.  *
  5.  *    12-89    -- Katie Stevens (dkstevens@ucdavis.edu)
  6.  *           UC Davis, Computing Services
  7.  *    PPP.08    05-90    [ks] include PPP protocol fields for VJ TCP compression
  8.  *    PPP.09    05-90    [ks] add UPAP negotiation and processing
  9.  *    PPP.10    07-90    [ks] make ppp open/close/reset work properly
  10.  *    PPP.14    08-90    [ks] change UPAP to PAP for consistency with RFC1172
  11.  *                 add RLSD link up/down signal handling
  12.  *                 add autobaud link speed message handling
  13.  *                 bit-shift constants must be explicitly long if shifted more than 8 bits
  14.  *                 must use unsigned char for comparison with SP_CHAR
  15.  *    PPP.15    09-90     [ks] update to KA9Q NOS v900828
  16.  *            framing routines revamped for speed - KA9Q 1/15/91
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include "global.h"
  21. #include "mbuf.h"
  22. #include "proc.h"
  23. #include "iface.h"
  24. #include "ax25.h"
  25. #include "slcompre.h"
  26. #include "ppp.h"
  27. #include "slip.h"
  28. #include "asy.h"
  29. #include "internet.h"
  30. #include "ip.h"
  31. #include "config.h"
  32. #include "trace.h"
  33.  
  34. /*#include "pktdrvr.h"*/
  35. /*#include "trace.h"*/
  36.  
  37. /* In pppcmd.c */
  38. extern int Ppptrace;
  39.  
  40. /* Counter for PPP id field */
  41. unsigned char Pppid;
  42.  
  43.  
  44. /* Routines local to this file */
  45. static struct mbuf *htonppp __ARGS((struct ppphdr *ppp, struct mbuf *data,
  46.     int accomp, int prcomp));
  47. static struct mbuf *ppp_decode __ARGS((struct slip *sp,unsigned char c));
  48. static struct mbuf *ppp_encode __ARGS((struct mbuf *bp,int32 ctlmap));
  49.  
  50. /*
  51.  * FCS lookup table as generated by fcsgen.c
  52.  */
  53. static unsigned short fcstab[256] = {
  54.     0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 
  55.     0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 
  56.     0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 
  57.     0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 
  58.     0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 
  59.     0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 
  60.     0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 
  61.     0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 
  62.     0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 
  63.     0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 
  64.     0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 
  65.     0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 
  66.     0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 
  67.     0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 
  68.     0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 
  69.     0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 
  70.     0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 
  71.     0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 
  72.     0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 
  73.     0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 
  74.     0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 
  75.     0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 
  76.     0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 
  77.     0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 
  78.     0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 
  79.     0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 
  80.     0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 
  81.     0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 
  82.     0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 
  83.     0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 
  84.     0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 
  85.     0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
  86. };
  87. #define pppfcs(fcs, c)        ((fcs >> 8) ^ fcstab[(fcs ^ c) & 0x00ff])
  88. #define SP_CHAR            0x20
  89.  
  90. /****************************************************************************/
  91.  
  92. /* Convert PPP header in host form to network form */
  93. static struct mbuf *
  94. htonppp(ppp, data, accomp, prcomp)
  95. struct ppphdr *ppp;
  96. struct mbuf *data;
  97. int accomp;    /* Compress address/control fields? */
  98. int prcomp;    /* Compress protocol field? */
  99. {
  100.     struct mbuf *bp;
  101.     register char *cp;
  102.     int hdrlen;
  103.  
  104.     if(ppp->type >= 256)
  105.         prcomp = 0;    /* Can't compress large values */
  106.     hdrlen = accomp ? 0 : 2;
  107.     hdrlen += prcomp ? 1 : 2;
  108.     /* Prepend header onto packet data */
  109.     if ((bp = pushdown(data, hdrlen)) == NULLBUF)
  110.         return NULLBUF;
  111.  
  112.     /* Load header with proper values */
  113.     cp = bp->data;
  114.     if(!accomp){
  115.         *cp++ = ppp->addr;
  116.         *cp++ = ppp->control;
  117.     }
  118.     if(prcomp)
  119.         *cp = ppp->type;
  120.     else
  121.         put16(cp,ppp->type);
  122.  
  123.     return bp;
  124. }
  125.  
  126. /* Extract PPP header from incoming packet. Applies a heuristic to determine
  127.  * if address/control compression is in use: if the frame begins with 0xff,
  128.  * compression is off, otherwise it is on.
  129.  */
  130. int
  131. ntohppp(ppp, bpp)
  132. struct ppphdr *ppp;
  133. struct mbuf **bpp;
  134. {
  135.     int c;
  136.  
  137.     if((c = pullchar(bpp)) == -1)
  138.         return -1;
  139.     if(c != HDLC_ALL_ADDR){
  140.         /* Compressed header */
  141.         ppp->addr = HDLC_ALL_ADDR;
  142.         ppp->control = HDLC_UI;
  143.     } else {
  144.         ppp->addr = c;
  145.         if((c = PULLCHAR(bpp)) == -1)
  146.             return -1;
  147.         ppp->control = c;
  148.         if((c = pullchar(bpp)) == -1)
  149.             return -1;
  150.     }
  151.     ppp->type = c;
  152.     if((c & 1) == 0){    /* Must be another byte */
  153.         ppp->type <<= 8;
  154.         if((c = pullchar(bpp)) == -1)
  155.             return -1;
  156.         ppp->type |= c;
  157.     }
  158.     return(PPP_HDRLEN);
  159. }
  160.  
  161. /****************************************************************************/
  162.  
  163. /* Send IP datagram with Point-to-Point Protocol */
  164. int
  165. ppp_send(bp,iface,gateway,prec,del,tput,rel)
  166. struct mbuf *bp;    /* Buffer to send */
  167. struct iface *iface;    /* Pointer to interface control block */
  168. int32 gateway;        /* Ignored (PPP is point-to-point) */
  169. int prec;
  170. int del;
  171. int tput;
  172. int rel;
  173. {
  174.     int type = PPP_IP_TYPE;
  175.     register struct slip *sp;
  176.     register struct slcompress *scp;
  177.  
  178.     if(iface == NULLIF){
  179.         free_p(bp);
  180.         return -1;
  181.     }
  182.     sp = &Slip[iface->xdev];
  183.     if (sp->pppio->ipcpio.ipcp_state != IPCP_OPEN) {
  184.         free_p(bp);
  185.         sp->pppio->snderr++;
  186.         return -1;
  187.     }
  188.     if (sp->escaped & PPP_XMT_VJCOMPR) {
  189.         /* Look for TCP packets */
  190.         scp = sp->slcomp;
  191.         /* Attempt IP/TCP header compression */
  192.         type = sl_compress_tcp(&bp, scp, 1);
  193.         switch(type) {
  194.         case SL_TYPE_IP:
  195.             type = PPP_IP_TYPE;
  196.             break;
  197.         case SL_TYPE_COMPRESSED_TCP:
  198.             type = PPP_COMPR_TYPE;
  199.             break;
  200.         case SL_TYPE_UNCOMPRESSED_TCP:
  201.             type = PPP_UNCOMP_TYPE;
  202.             break;
  203.         default:
  204.             return -1;
  205.         }
  206.     }
  207.     sp->pppio->sndip++;
  208.     return (*iface->output)(iface,NULLCHAR,NULLCHAR,type,bp);
  209. }
  210. /* Send a packet with PPP header */
  211. int
  212. ppp_output(iface,dest,source,type,data)
  213. struct iface *iface;    /* Pointer to interface control block */
  214. char *dest;        /* Dest addr (ignored; PPP is point-to-point) */
  215. char *source;        /* Source addr (ignored; PPP is point-to-point) */
  216. int16 type;        /* PPP Protocol Type field */
  217. struct mbuf *data;    /* Actual data to be sent */
  218. {
  219.     struct slip *sp;
  220.     struct ppphdr ppp;
  221.     struct mbuf *bp;
  222.  
  223.     sp = &Slip[iface->xdev];
  224.     if (sp->pppio->state == PPP_CLOSED) {
  225.         free_p(data);
  226.         sp->pppio->snderr++;
  227.         return -1;
  228.     }
  229.     ppp.addr = HDLC_ALL_ADDR;
  230.     ppp.control = HDLC_UI;
  231.     ppp.type = type;
  232.     if ((bp = htonppp(&ppp,data,sp->escaped & PPP_XMT_ACCOMP,sp->escaped & PPP_XMT_PRCOMP)) == NULLBUF) {
  233.         free_p(data);
  234.         return -1;
  235.     }
  236.     return (*iface->raw)(iface,bp);
  237. }
  238. /* Encode a raw packet in PPP framing, put on link output queue, and kick
  239.  * transmitter
  240.  */
  241. int
  242. ppp_raw(iface,bp)
  243. struct iface *iface;
  244. struct mbuf *bp;
  245. {
  246.     register struct slip *sp;
  247.     struct mbuf *bp1;
  248.  
  249.     sp = &Slip[iface->xdev];
  250.     dump(iface,IF_TRACE_OUT,sp->type,bp);
  251.     iface->rawsndcnt++;
  252.     iface->lastsent = secclock();
  253.     /* Queue a frame on the PPP output queue and start transmitter */
  254.     if ((bp1 = ppp_encode(bp,sp->pppio->ctlmap)) == NULLBUF)
  255.         return -1;    
  256.     if (iface->trace & IF_TRACE_RAW)
  257.         raw_dump(iface,IF_TRACE_OUT,bp1);
  258.     sp->pppio->sndpkt++;
  259.     return Slip[iface->xdev].send(iface->dev,bp1);
  260. }
  261.  
  262. /* Encode a packet in PPP format */
  263. static
  264. struct mbuf *
  265. ppp_encode(bp,ctlmap)
  266. struct mbuf *bp;
  267. int32 ctlmap;
  268. {
  269.     struct mbuf *lbp;    /* Mbuf containing line-ready packet */
  270.     register char *cp;
  271.     int c;
  272.     int16 calc_fcs;
  273.  
  274.     /* Allocate output mbuf that's twice as long as the packet.
  275.      * This is a worst-case guess (consider a packet full of HDLC_FLAGs!)
  276.      */
  277.     lbp = alloc_mbuf((int16)(2*len_p(bp) + HDLC_ENVLEN));
  278.     if(lbp == NULLBUF){
  279.         /* No space; drop */
  280.         free_p(bp);
  281.         return NULLBUF;
  282.     }
  283.     cp = lbp->data;
  284.  
  285.     /* Flush out any line garbage */
  286.     *cp++ = HDLC_FLAG;
  287.  
  288.     /* Initialize FCS */
  289.     calc_fcs = HDLC_FCS_START;
  290.  
  291.     /* Copy input to output, escaping special characters */
  292.     while ((c = PULLCHAR(&bp)) != -1) {
  293.         /* Fold char value into FCS calculated so far */
  294.         calc_fcs = pppfcs(calc_fcs, c);
  295.  
  296.         if ( ((c < SP_CHAR) && (ctlmap & (1L << c)))
  297.             || (c == HDLC_ESC_ASYNC)
  298.             || (c == HDLC_FLAG)) {
  299.             *cp++ = HDLC_ESC_ASYNC;
  300.             *cp++ = (c ^ HDLC_ESC_COMPL);
  301.         } else {
  302.             *cp++ = c;
  303.         }
  304.     }
  305.  
  306.     /* Final FCS calculation */
  307.     calc_fcs ^= 0xffff;
  308.     c = (calc_fcs & 0x00ff);    /* Least significant byte first */
  309.     if ( ((c < SP_CHAR) && (ctlmap & (1L << c)))
  310.          ||(c == HDLC_ESC_ASYNC)
  311.          ||(c == HDLC_FLAG)) {
  312.         *cp++ = HDLC_ESC_ASYNC;
  313.         *cp++ = (c ^ HDLC_ESC_COMPL);
  314.     } else {
  315.         *cp++ = c;
  316.     }
  317.     c = (calc_fcs >> 8);        /* Most significant byte next */
  318.     if ( ((c < SP_CHAR) && (ctlmap & (1L << c)))
  319.          ||(c == HDLC_ESC_ASYNC)
  320.          ||(c == HDLC_FLAG)) {
  321.         *cp++ = HDLC_ESC_ASYNC;
  322.         *cp++ = (c ^ HDLC_ESC_COMPL);
  323.     } else {
  324.         *cp++ = c;
  325.     }
  326.  
  327.     /* Tie off the packet */
  328.     *cp++ = HDLC_FLAG;
  329.     lbp->cnt = cp - lbp->data;
  330.     return lbp;
  331. }
  332. /* Process incoming bytes in PPP format
  333.  * When a buffer is complete, return it; otherwise NULLBUF
  334.  */
  335. static
  336. struct mbuf *
  337. ppp_decode(sp,c)
  338. register struct slip *sp;
  339. unsigned char c;    /* Incoming character */
  340. {
  341.     struct mbuf *bp;
  342.     register struct pppctl *pppiop;
  343.  
  344.     pppiop = sp->pppio;
  345.     switch(c){
  346.     case HDLC_FLAG:                /* Start/end of packet */
  347.         /* Wrap it up if end of a packet */
  348.         if (sp->rbp != NULLBUF) {
  349.             if (pppiop->calc_fcs == HDLC_FCS_FINAL) {
  350.                 /* Good packet, trim off FCS bytes */
  351.                 trim_mbuf(&sp->rbp, (len_p(sp->rbp)-2));
  352.             } else {
  353.                 /* FCS doesnt match; discard packet */
  354. /*putchar('\007');*/
  355.                 free_p(sp->rbp);
  356.                 sp->rbp = NULLBUF;
  357.                 sp->rcnt = 0;
  358.                 pppiop->csumerr++;
  359.             }
  360.         }
  361.         /* Prepare for next packet */
  362.         bp = sp->rbp;
  363.         sp->escaped &= ~PPP_BIT_BUCKET;
  364.         sp->escaped &= ~PPP_ESCAPED;
  365.         sp->rbp = NULLBUF;
  366.         sp->rcnt = 0;
  367.         pppiop->calc_fcs = HDLC_FCS_START;
  368.         return bp;    /* Will be NULLBUF if empty frame */
  369.  
  370.     case HDLC_ESC_ASYNC:            /* Async HDLC escape char */
  371.         sp->escaped |= PPP_ESCAPED;
  372.         return NULLBUF;
  373.     }
  374.  
  375.     if(sp->escaped & PPP_BIT_BUCKET)
  376.         /* Eat bytes til end of packet */
  377.         return NULLBUF;
  378.  
  379.     if(sp->escaped & PPP_ESCAPED){
  380.         /* Translate 2-char escape sequence back to original char */
  381.         sp->escaped &= ~PPP_ESCAPED;
  382.         c ^= HDLC_ESC_COMPL;
  383.     }
  384.     /* We reach here with a character for the buffer;
  385.      * make sure there's space for it
  386.      */
  387.     if(sp->rbp == NULLBUF){
  388.         /* Allocate first mbuf for new packet */
  389.         if((sp->rbp1 = sp->rbp = alloc_mbuf(PPP_ALLOC)) == NULLBUF)
  390.             return NULLBUF; /* No memory, drop */
  391.         sp->rcp = sp->rbp->data;
  392.     } else if(sp->rbp1->cnt == PPP_ALLOC){
  393.         /* Current mbuf is full; link in another */
  394.         if((sp->rbp1->next = alloc_mbuf(PPP_ALLOC)) == NULLBUF){
  395.             /* No memory, drop whole thing */
  396.             free_p(sp->rbp);
  397.             sp->rbp = NULLBUF;
  398.             sp->rcnt = 0;
  399.             return NULLBUF;
  400.         }
  401.         sp->rbp1 = sp->rbp1->next;
  402.         sp->rcp = sp->rbp1->data;
  403.     }
  404.     /* Store the character, increment fragment and total
  405.      * byte counts
  406.      */
  407.     /* Now add the actual character */
  408.     *sp->rcp++ = c;
  409.     sp->rbp1->cnt++;
  410.     sp->rcnt++;
  411.     pppiop->calc_fcs = pppfcs(pppiop->calc_fcs, c);
  412.     return NULLBUF;
  413. }
  414. /* Process PPP line input */
  415. void
  416. ppp_recv(dev,p1,p2)
  417. int dev;
  418. void *p1;
  419. void *p2;
  420. {
  421.     unsigned char c;
  422.     struct mbuf *bp,*nbp;
  423.     struct phdr phdr;
  424.     struct slip *sp;
  425.     int cdev;
  426.  
  427.     sp = &Slip[dev];
  428.     cdev = sp->iface->dev;
  429.  
  430.     for(;;){
  431.         c = sp->get(cdev);
  432.         if((bp = ppp_decode(sp,c)) == NULLBUF)
  433.             continue;    /* More to come */
  434.  
  435.         if((nbp = pushdown(bp,sizeof(phdr))) == NULLBUF){
  436.             free_p(bp);
  437.             continue;
  438.         }
  439.         phdr.iface = sp->iface;
  440.         phdr.type = sp->type;
  441.         memcpy(&nbp->data[0],(char *)&phdr,sizeof(phdr));
  442.         enqueue(&Hopper,nbp);
  443.         /* Especially on slow machines, serial I/O can be quite
  444.          * compute intensive, so release the machine before we
  445.          * go for the next packet. This will allow this packet to
  446.          * go on to its ultimate destination, helping pipelining
  447.          */
  448.         pwait(NULL);
  449.     }
  450. }
  451.  
  452. /****************************************************************************/
  453.  
  454. /* Wait for autobaud message to set line speed then switch to regular PPP */
  455. void
  456. ppp_autobaud(dev,p1,p2)
  457. int dev;
  458. void *p1;
  459. void *p2;
  460. {
  461.     struct slip *sp;
  462.     struct iface *ifp;
  463.  
  464.     sp = &Slip[dev];
  465.     ifp = sp->iface;
  466.     /* Wait for an autobaud message */
  467.     asy_autobaud(ifp->dev);
  468.  
  469.     /* Ready for PPP packets */
  470.     ifp->rxproc = newproc("ppp recv", 256, ppp_recv, ifp->xdev, NULL, NULL,0);
  471.  
  472.     /* The LCP state machine has been waiting for us */
  473.     sp->pppio->state = PPP_CLOSED;
  474.     lcp_reset(sp->pppio);
  475.     lcp_start(sp);
  476.  
  477.     /* Terminate this process */
  478.     return;
  479. }
  480.  
  481. /* Keep track of RLSD signal; if RLSD is down, physical layer is down;
  482.  * if RLSD is asserted, physical layer is ready for traffic
  483.  */
  484. void
  485. ppp_rlsd(dev,p1,p2)
  486. int dev;
  487. void *p1;
  488. void *p2;
  489. {
  490.     int last_rlsd = 1;
  491.     int i;
  492.     unsigned long autospeed;
  493.     struct slip *sp;
  494.     struct pppctl *pppiop;
  495.     struct ipcpctl *ipcpiop;
  496.  
  497.     autospeed = (unsigned long)p1;
  498.     sp = &Slip[dev];
  499.     pppiop = sp->pppio;
  500.     for ( ; ; ) {
  501.         /* Wait for RLSD to change */
  502.         if (last_rlsd == 1) {
  503.             /* Down now, wait for RSLD to be asserted */
  504.             i = sp->get_rlsd(sp->iface->dev, 100);
  505.         } else {
  506.             /* Asserted now, wait for RSLD to be dropped */
  507.             i = sp->get_rlsd(sp->iface->dev, 1);
  508.         }
  509.  
  510.         last_rlsd = i;
  511. /*
  512. printf("ppp_rlsd: rlsd state change: %d\n",last_rlsd);
  513.  */
  514.         if (last_rlsd == 100) {
  515.             /* Physical layer now open for traffic */
  516.             if (Ppptrace)
  517.                 log(-1,"%s: PPP/RLSD: Physical layer ready",
  518.                     sp->iface->name);
  519.             /* RLSD signal is asserted */
  520.             if (pppiop->state == PPP_PL_DOWN) {
  521.                 if (autospeed == 0L) {
  522.                     pppiop->state = PPP_CLOSED;
  523.                     lcp_reset(pppiop);
  524.                     lcp_start(sp);
  525.                 } else {
  526.                     pppiop->state = PPP_AUTOBAUD;
  527.                 }
  528.             }
  529.         } else {
  530.             /* Physical layer is down */
  531.             if (Ppptrace)
  532.                 log(-1,"%s: PPP/RLSD: Physical layer down",
  533.                     sp->iface->name);
  534.             /* RLSD signal not asserted */
  535.             if ((pppiop->state != PPP_CLOSED) &&
  536.                 (pppiop->state != PPP_AUTOBAUD)) {
  537.                 ipcpiop = &(pppiop->ipcpio);
  538.                 if (ipcpiop->ipcp_state == IPCP_OPEN) {
  539.                     /* Remove routing entry from table */
  540.                     rt_drop(ipcpiop->attempt_dest,
  541.                         (unsigned int)32);
  542.                 }
  543.                 /* Blast any layers that are open */
  544.                 ipcp_reset(sp);
  545.                 pap_init(sp);
  546.                 lcp_reset(pppiop);
  547.             }
  548.             /* Physical layer closed to all traffic */
  549.             pppiop->state = PPP_PL_DOWN;
  550.             if (autospeed != 0L) {
  551.                 killproc(sp->iface->rxproc);
  552.                 sp->iface->rxproc = NULLPROC;
  553.                 sp->iface->rxproc = newproc("ppp autobaud", 256,
  554.                               ppp_autobaud, sp->iface->xdev, NULL, NULL,0);
  555.             }
  556.         }
  557.     }
  558. }
  559.  
  560. /****************************************************************************/
  561.  
  562. /* Initialize PPP control structures for a Point-to-Point interface */
  563. int
  564. ppp_init(dev,rlsd,autospeed)
  565. int dev;
  566. char rlsd;
  567. long autospeed;
  568. {
  569.     struct slip *sp;
  570.     struct pppctl *pppiop;
  571.  
  572.     sp = &Slip[dev];
  573.     pppiop = sp->pppio;
  574.  
  575.     if (rlsd != 0)
  576.         pppiop->state = PPP_PL_DOWN;    /* Must wait for RLSD signal */
  577.     else if (autospeed != 0L)
  578.         pppiop->state = PPP_AUTOBAUD;    /* Wait for link speed msg */
  579.     else
  580.         pppiop->state = PPP_CLOSED;    /* Ready for traffic */
  581.     pppiop->ctlmap = DEF_CTL_MAP;    /* Overall PPP parameters */
  582.  
  583.     lcp_init(sp);            /* Link Control parameters */
  584.     pap_init(sp);            /* Peer Authentication parameters */
  585.     ipcp_init(sp);            /* IP Control parameters */
  586.  
  587.     return 0;
  588. }
  589.  
  590. /* Close the PPP interface */
  591. int
  592. ppp_close(sp,pl_too)
  593. struct slip *sp;
  594. int pl_too;
  595. {
  596.     int argc = 2;
  597.     char *argv[] = {
  598.         "dtr",
  599.         "0",
  600.     };
  601.  
  602.     ipcp_close(sp);            /* Close IP layer */
  603.     lcp_close(sp);            /* Close Link layer */
  604.     if (pl_too) {            /* Close physical layer */
  605.         sp->iface->ioctl(sp->iface,argc,argv);
  606.     }
  607.     sp->pppio->lcpio.active = -1;    /* We are strictly closed */
  608.     tprintf("PPP interface  %s  closed\n",sp->iface->name);
  609.     return 0;
  610. }
  611.  
  612.  
  613. /* Process incoming PPP packets */
  614. void
  615. pproc(iface,bp)
  616. struct iface *iface;
  617. struct mbuf *bp;
  618. {
  619.     struct ppphdr hdr;
  620.     struct pppctl *pppiop;
  621.     struct slip *sp;
  622.     register int16 len;
  623.  
  624.     sp = &Slip[iface->xdev];
  625.     pppiop = Slip[iface->xdev].pppio;
  626.     pppiop->rcvpkt++;
  627.     /* Remove PPP header and kick packet upstairs */
  628.     ntohppp(&hdr, &bp);
  629.     switch(hdr.type) {
  630.     case PPP_IP_TYPE:    /* Regular IP */
  631.         if ((pppiop->ipcpio.ipcp_state != IPCP_OPEN) &&
  632.             (pppiop->ipcpio.ipcp_state != IPCP_TERMINATE)) {
  633.             if (Ppptrace)
  634.                 log(-1,"PPP link not open for IP traffic; dropping IP packet");
  635.             pppiop->rcverr++;
  636. /*
  637. printf("rcverr: link not open for IP\n");
  638. fflush(stdout);
  639.  */
  640.             free_p(bp);
  641.             break;
  642.         }
  643.         pppiop->rcvip++;
  644.         if (sp->escaped & PPP_RCV_VJCOMPR) {
  645.             if(bp->data[9] == TCP_PTCL)    /* FIX THIS! */
  646.                 sp->slcomp->sls_tcpin++;
  647.             else
  648.                 sp->slcomp->sls_nontcpin++;
  649.         }
  650.         ip_route(iface,bp,0);
  651.         break;
  652.     case PPP_COMPR_TYPE:    /* Van Jacobson Compressed TCP/IP */
  653.         if (pppiop->ipcpio.ipcp_state != IPCP_OPEN) {
  654.             if (Ppptrace)
  655.                 log(-1,"PPP link not open for IP traffic; dropping Compressed TCP/IP packet");
  656.             pppiop->rcverr++;
  657. /*
  658. printf("rcverr: link not open for VJ Compr\n");
  659. fflush(stdout);
  660.  */
  661.             free_p(bp);
  662.             break;
  663.         }
  664.         if ((len = len_p(bp)) < 3) {
  665.             if (Ppptrace)
  666.                 log(-1,"VJ Compressed TCP/IP packet error: short");
  667.             free_p(bp);
  668.             pppiop->rcverr++;
  669. /*
  670. printf("rcverr: short VJ Compr pkt\n");
  671. fflush(stdout);
  672.  */
  673.             break;
  674.         }
  675.         /* Got a packet at least minimum length of
  676.          * a compressed packet
  677.          */
  678.         if ((sp->escaped & PPP_RCV_VJCOMPR) == 0) {
  679.             if (Ppptrace)
  680.                 log(-1,"VJ Compressed TCP/IP packet error: not enabled");
  681.             pppiop->rcverr++;
  682. /*
  683. printf("rcverr: VJ Compr not enabled\n");
  684. fflush(stdout);
  685.  */
  686.             free_p(bp);
  687.             break;
  688.         }
  689.         /* Got a packet other than regular IP */
  690.         len = sl_uncompress_tcp(&bp, len,
  691.             SL_TYPE_COMPRESSED_TCP,
  692.             sp->slcomp);
  693.         if (len <= 0) {
  694.             free_p(bp);
  695.             bp = NULLBUF;
  696.             pppiop->rcverr++;
  697. /*
  698. printf("rcverr: VJ Compr decompr error\n");
  699. fflush(stdout);
  700.  */
  701.             break;
  702.         }
  703.         pppiop->rcvip++;
  704.         ip_route(iface,bp,0);
  705.         break;
  706.     case PPP_UNCOMP_TYPE:    /* Van Jacobson Uncompressed TCP/IP */
  707.         if (pppiop->ipcpio.ipcp_state != IPCP_OPEN) {
  708.             if (Ppptrace)
  709.                 log(-1,"PPP link not open for IP traffic; dropping Uncompressed TCP/IP packet");
  710.             free_p(bp);
  711.             pppiop->rcverr++;
  712. /*
  713. printf("rcverr: link not open for VJ uncompr\n");
  714. fflush(stdout);
  715.  */
  716.             break;
  717.         }
  718.         if ((len = len_p(bp)) < 3) {
  719.             if (Ppptrace)
  720.                 log(-1,"VJ Uncompressed TCP/IP packet error: short");
  721.             free_p(bp);
  722.             pppiop->rcverr++;
  723. /*
  724. printf("rcverr: short VJ Uncompr pkt\n");
  725. fflush(stdout);
  726.  */
  727.             break;
  728.         }
  729.         /* Got a packet at least minimum length of
  730.          * a compressed packet
  731.          */
  732.         if ((sp->escaped & PPP_RCV_VJCOMPR) == 0) {
  733.             if (Ppptrace)
  734.                 log(-1,"VJ Uncompressed TCP/IP packet error: not enabled");
  735.             free_p(bp);
  736.             pppiop->rcverr++;
  737. /*
  738. printf("rcverr: VJ Uncompr not enabled\n");
  739. fflush(stdout);
  740.  */
  741.             break;
  742.         }
  743.         /* Got a packet other than regular IP */
  744.         len = sl_uncompress_tcp(&bp, len,
  745.             SL_TYPE_UNCOMPRESSED_TCP,
  746.             sp->slcomp);
  747.         if (len <= 0) {
  748.             free_p(bp);
  749.             bp = NULLBUF;
  750.             pppiop->rcverr++;
  751. /*
  752. printf("rcverr: VJ Uncompr decompr error\n");
  753. fflush(stdout);
  754.  */
  755.             break;
  756.         }
  757.         pppiop->rcvip++;
  758.         ip_route(iface,bp,0);
  759.         break;
  760.     case PPP_LCP_TYPE:    /* Link Control Protocol */
  761.         pppiop->rcvlcp++;
  762.         lcpproc(iface,bp);
  763.         break;
  764.     case PPP_PAP_TYPE:    /* Password Authenticate Protocol */
  765.         if (pppiop->lcpio.lcp_state != LCP_OPEN) {
  766.             if (Ppptrace)
  767.                 log(-1,"not in PAP phase; dropping PAP packet");
  768.             free_p(bp);
  769.             pppiop->rcverr++;
  770. /*
  771. printf("rcverr: not open for PAP\n");
  772. fflush(stdout);
  773.  */
  774.             break;
  775.         }
  776.         pppiop->rcvpap++;
  777.         papproc(iface,bp);
  778.         break;
  779.     case PPP_IPCP_TYPE:    /* IP Control Protocol */
  780.         if (pppiop->lcpio.lcp_state != LCP_OPEN) {
  781.             if (Ppptrace)
  782.                 log(-1,"IPCP closed; dropping IPCP packet");
  783.             free_p(bp);
  784.             pppiop->rcverr++;
  785. /*
  786. printf("rcverr: not open for IPCP\n");
  787. fflush(stdout);
  788.  */
  789.             break;
  790.         }
  791.         pppiop->rcvipcp++;
  792.         ipcpproc(iface,bp);
  793.         break;
  794.     default:
  795.         if (Ppptrace)
  796.             log(-1,"Unknown PPP packet type: %x; dropping packet",hdr.type);
  797.         free_p(bp);
  798.         pppiop->rcvunk++;
  799.         break;
  800.     }
  801.     return;
  802. }
  803.